为什么我会得到表达式计算器程序的语法错误?

Why do I get syntax error for the expression evaluator program?

我尝试了以下输入

一个=10;

打印一个;

打印 1+2+3;

一=5+10;

当我尝试使用上述输入执行文件时出现语法错误 编译没有报错

这是代码

弹性

%{
/* header files */
%}

/* regex */

%option yylineno

%%


"println"       {  printf("token is println");  return(TOK_PRINTLN);}
"print" { printf("token is print"); return(TOK_PRINTLN); }

"main()" { return(TOK_MAIN); }
{digit}+    {  /* convert to int and store its val*/
              printf("token is %d", yylval.int_val);
            return INTEGER;
            }
{id} {
      /* convert to char */
      printf("token is %c", yylval.id_val);
      return(TOK_ID);
     } 

";" {   return(TOK_SEMICOLON);  }
"+" {   return(TOK_ADD);    }
"-" {   return(TOK_SUB);    } /* not req  */
"*" {   return(TOK_MUL);    }
"/" {   return(TOK_DIV);    } /* not req  */
"=" { return(TOK_EQ);   }
[ \t\n]     {printf("token is space");}

.   {printf("Invalid character '%c', ignored\n", 
        yytext[0]);
    }

%%

对于野牛,我们使用一个符号table,它是一个数组。 我们获取变量(由 TOK_ID 表示的标识符)并将其转换为索引,我们可以在其中存储表达式的值。

野牛档案

%{
  /* header file and fucn dec*/
%}


%union{
    int int_val;
    char id_val;       
      }

/* 标记和类型 */ %开始 stmt

%right TOK_EQ
%left TOK_ADD TOK_SUB
%left TOK_MUL TOK_DIV


%%

 /* grammar */

stmt: expr_stmt TOK_SEMICOLON
     {; /* do nothing*/
     }
     | TOK_PRINTLN expr TOK_SEMICOLON 
     {
      printf("%d \n",);
     }
     | stmt TOK_PRINTLN expr TOK_SEMICOLON
     {
     printf("%d \n",);
     }
     | stmt expr TOK_SEMICOLON
     {
     ;
     }
;

expr_stmt: TOK_ID TOK_EQ expr
       {
        setSTVal(, );
       }
;

expr:
   /*expr stuff */

;

%%

int getSTIndex(char c){
  /* return index*/
}

int getSTVal(char c){
  /* set val*/
}

void setSTVal(char c, int v){
   /* set table val*/
 }


 int yyerror(char *s)
{

 printf("\nsyntax error on line no %d\n",yylineno);
return 0;
 }

void initializeSymbolTable(){
    for(int i=0; i<100; i++)symbol_table[i] = 0; /*avoiding garbage val*/
         /* initializn stuff */
 }

 int main()
 {
  initializeSymbolTable();
  yyparse(); /* C routine produced by lex */
  return 0;
  }

当我尝试使用输入 a=5 进行调试时;和一个= 5; 它可以捕获令牌 a 但之后会抛出语法错误 它无法捕获 = 以及之后的所有内容。

我不明白为什么它只捕获第一个 digit/command/string 然后抛出语法错误

如果我把你的语法稍微简化一下

/* ... */
%start input
/* ... */

input: /* empty file/no input */
     | input stmt

/* each statement is an "expr" followed by a semicolon */
stmt: expr TOK_SEMICOLON
     {
       ;
     }
     /* This is a function and should go into the rule "expr", too, btw. */
     | TOK_PRINTLN expr TOK_SEMICOLON 
     {
      printf("%d \n",);
     }
;


expr: /* empty expression */
    expr TOK_ADD expr
    {
    $$ =  + ;
    }
    /* ... */
    | INTEGER
    {
     $$ = ;
    };
    | TOK_ID
    {
     $$ =  getSTVal();
    }
    | TOK_ID TOK_EQ expr
    {
      setSTVal(, );
    }
  ;

它适用于输入文件

a = 10;

print
   a;

print 1+2+3;

a = 5
     +
      10;
print a;

符合预期。它不是很优雅,但应该为您指明正确的方向。

你的问题是 TOK_ID 在两个规则中,第二次出现 TOK_EQ 时解析器在 expr 并且没有 TOK_ID TOK_EQ 的规则仅 TOK_ID 一个人。 (比那复杂一点,承认)

如果您手边有 Bison 文档,您可以查找 mfcalc 示例。