为什么我的表达式求值器程序出现语法错误? [关闭]

问题描述 投票:0回答:1

我尝试了以下输入

a = 10;

打印a;

打印1 + 2 + 3;

a = 5 + 10;

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

这里是代码

Flex

%{
/* 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]);
    }

%%

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

野牛文件

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


%union{
    int int_val;
    char id_val;       
      }

/ *标记和类型* /%start 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",$2);
     }
     | stmt TOK_PRINTLN expr TOK_SEMICOLON
     {
     printf("%d \n",$3);
     }
     | stmt expr TOK_SEMICOLON
     {
     ;
     }
;

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

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进行调试时;和a = 5;它可以捕获令牌a,但是此后引发语法错误它捕获了=和之后的所有内容。

我不知道为什么它只捕获第一个数字/命令/字符串,然后引发语法错误

c flex-lexer context-free-grammar bisonc++
1个回答
0
投票

如果我将您的语法稍微简化为

/* ... */
%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",$2);
     }
;


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

与输入文件一起使用

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示例。

© www.soinside.com 2019 - 2024. All rights reserved.