代码之家  ›  专栏  ›  技术社区  ›  Doasy

YACC+柔性。忽略空白效果不好

  •  1
  • Doasy  · 技术社区  · 7 年前

    我的问题是输入行中有空格。 我正在与Lex和Yacc合作,我有下一个文件:

    解释l

    %option noyywrap
    %{
    #include "interpret.tab.h"
    %}
    
    %x string
    %x substring
    %%
    
    [\t ]+      /* ignore whitespace */ ;
    "+"         { return SUM; }
    "-"         { return SUB; }
    "*"         { return MUL; }
    "/"         { return DIV; }
    
    "=="        { return EQ; }
    ">"         { return GT; }
    "<"         { return LT; }
    
    ":="        {return IS;}
    
    "("         { return LPAR; }
    ")"         { return RPAR; }
    
    "if"        { return IF; }
    "else"      { return ELSE; }
    "then"      { return THEN; }
    
    "print"     { return PRINT; }
    
    [a-z A-Z]+  { return ID; }
    [0-9]+      { yylval.i = atoi( yytext ); return INT; }
    
    [\n]        { return EOLN; }
    
    .           { printf("Illegal character %c: ", *yytext); }
    

    解释y

    %error-verbose
    %{
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdbool.h>
    
    char* int_to_string();
    char* reformat(char* sub);
    int yyerror();
    int yylex();
    %}
    
    %union {
      int b;
      int i;
    }
    
    %type <i> expr INT inst
    %type <b> expr_booleana
    
    %token SUM SUB MUL DIV
    %token EQ GT LT IS
    %token IF ELSE THEN
    %token ID
    %token INT
    %token LPAR RPAR
    %token EOLN
    %token PRINT
    
    %%
    
    expr_lst : 
        | expr_lst inst EOLN 
        ;
    
    
    inst : IF expr_booleana THEN {if($2){printf("true\n");}}
         | PRINT expr   {printf("print expr %i\n", $2);}
         ;
    
    expr_booleana: expr EQ expr { $$ = $1==$3; }
                 | expr GT expr { $$ = $1>$3; }
                 | expr LT expr { $$ = $1<$3;}
                 | LPAR expr_booleana RPAR { $$ = $2; }
                 ;
    
    expr : INT { $$ = $1; }
          | expr SUM expr   { $$ = $1 + $3; }
          | expr SUB expr   { $$ = $1 - $3; }
          | expr MUL expr   { $$ = $1 * $3; }
          | expr DIV expr   { $$ = $1 / $3; }
          | LPAR expr RPAR  { $$ = $2; }
          ;
    
    
    
    %%
    
    
    int yyerror( char* m ) {
       fprintf( stderr, "%s\n", m );
    }
    
    int main() {
      return yyparse();
    }
    

    YACC程序尚未完成 编译时,它不会显示警告。

    我的问题是像“if(4>2)then”这样的输入。控制台显示消息“语法错误,意外ID,应为THEN”。

    如果我不写空格,一切都好。 我不明白,因为“[\t]+/*忽略空格*/;”这一行在解释中。写l的目的是忽略空格。。。

    你能帮帮我吗?

    提前谢谢你。

    1 回复  |  直到 7 年前
        1
  •  4
  •   rici    7 年前
    [a-z A-Z]+  { return ID; }
    

    表示ID可以是小写字母、空格或大写字母。因此,“then”(带前导空格)是一个ID。(它优先于您的空格模式,因为匹配的时间更长。)

    还要考虑数字是否应该是不正确的,如 times2 。常见的id模式是

    [[:alpha:]_][[:alnum:]_]*