算术表达式在 yacc 文法中未正确解析

Arithmetic expression nor properly parsed in yacc grammar

我有以下 yacc:

%{
#include  <stdio.h>
extern FILE* yyin;
extern char* yytext;

%}

%token VAR ID_NAME TYPE_STRING TYPE_BOOL TYPE_NUMBER
%token CONST VALUE_STRING VALUE_BOOL VALUE_NUMBER

%left '*' '/'
%left '+' '-'

%%

program
    : declarations
    ;

declarations
    : declaration
    | declarations declaration
    ;

declaration
    : var_declaration
    | const_declaration
    ;

value
    : VALUE_BOOL
    | VALUE_STRING
    ;

arithmetic_expression
    : arithmetic_expression '+' arithmetic_expression
    | arithmetic_expression '-' arithmetic_expression
    | arithmetic_expression '*' arithmetic_expression
    | arithmetic_expression '/' arithmetic_expression
    | '(' arithmetic_expression ')'
    | VALUE_NUMBER
    ;

initializer
    : value
    | arithmetic_expression
    ;

initialization
    : ID_NAME '=' initializer
    ;

init_list
    : initialization
    | init_list ',' initialization
    ;

init_or_id
    : initialization
    | ID_NAME
    ;

init_or_id_list
    : init_or_id
    | init_or_id_list ',' init_or_id
    ;

var_declaration
    : VAR ':' type init_or_id_list ';' { printf("%s booyah\n", );  } 
    ;

const_declaration: CONST ':' type init_list ';' {printf("koskos\n");}
    ;

type: TYPE_NUMBER 
    | TYPE_STRING
    | TYPE_BOOL
    ;

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

int main(int argc, char** argv[])
{

    yyparse();
    return 0;
}

其中一个功能应该是允许用户使用算术表达式(的值)来初始化变量和常量。像这样 var:number = (1+2+3);。但是,我不确定为什么,但是解析器只识别使用运算符 */ 的表达式。当我使用使用运算符 +-.

的表达式时出现语法错误

这是关联的 lex 文件:

%{

#include <stdio.h>
#include "y.tab.h"

%}

id_name [a-zA-Z]([a-zA-Z0-9])*
value_string \"([a-zA-Z0-9*+z=])*\"
value_number [+-]?([0-9]*[.])?[0-9]+

%%

"var"                   { return VAR;  }
"const"                 { return CONST; }
"string"                { return TYPE_STRING; }
"number"                { return TYPE_NUMBER; }
"bool"                  { return TYPE_BOOL; }
"true"                  { return VALUE_BOOL; }
"false"                 { return VALUE_BOOL; }

{value_number}          { return VALUE_NUMBER; }
{value_string}          { return VALUE_STRING; }
{id_name}               { return ID_NAME; }


","                     { return ','; }
":"                     { return ':'; }
";"                     { return ';'; }
"="                     { return '='; }
"+"                     { return '+'; }
"-"                     { return '-'; }
"*"                     { return '*'; }
"/"                     { return '/'; }
"("                     { return '('; }
")"                     { return ')'; }


%%

我使用以下命令编译文件:

yacc -vd grammar.y
flex -l lex.l
gcc -Wall -o lang lex.yy.c y.tab.c -ll -lfl

例如这个表达式:var:number var1=12*12;被成功识别。但是这个:var:number var1=12+12; 结果是 syntax error。我不确定我错了什么。

尝试使用 flex --debug 选项。这将生成一个扫描仪,向您显示它正在做什么的痕迹。我想你很快就会发现问题。

剧透

+12 被词法化为单个数字标记,而不是后跟数字的运算符