YACC+FLEX。忽略空格效果不佳

YACC+FLEX. ignore whitespace doesn't work well

我的问题是输入行中的白色space。 我正在使用 Lex 和 Yacc,并且我有下一个文件:

interpret.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); }

interpret.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(){printf("true\n");}}
     | PRINT expr   {printf("print expr %i\n", );}
     ;

expr_booleana: expr EQ expr { $$ = ==; }
             | expr GT expr { $$ = >; }
             | expr LT expr { $$ = <;}
             | LPAR expr_booleana RPAR { $$ = ; }
             ;

expr : INT { $$ = ; }
      | expr SUM expr   { $$ =  + ; }
      | expr SUB expr   { $$ =  - ; }
      | expr MUL expr   { $$ =  * ; }
      | expr DIV expr   { $$ =  / ; }
      | LPAR expr RPAR  { $$ = ; }
      ;



%%


int yyerror( char* m ) {
   fprintf( stderr, "%s\n", m );
}

int main() {
  return yyparse();
}

YACC 程序根本没有完成 当我编译时,它没有显示警告。

我的问题是 "if(4>2) then" 这样的输入。控制台显示消息 "syntax error, unexpected ID, expecting THEN"。

如果我不写 space 就可以了。 我不明白,因为行“[\t ]+ /* ignore whitespace */ ;” in interpret.l 是为了忽略 whitespaces...

而写的

你能帮帮我吗?

提前致谢。

[a-z A-Z]+  { return ID; }

表示ID可以是小写字母,spaces,也可以是大写字母。因此“then”(前导 space)是一个 ID。 (它优先于你的 whitespace 模式,因为匹配更长。)

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

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