野牛意外标识符错误

时间:2015-02-27 03:36:56

标签: grammar bison yacc flex-lexer lex

我在第1-9行的

上收到“意外标识符错误”
string_op   | string_lit                { $$ = $1; }

这是我的语法

%union 
{
    int intval;
    double dubval;
    char* strval;   
    obj object;
}

%token <intval> INTEGER 
%token <dubval> DOUBLE 
%token <strval> STRING_LITERAL

%type <object> number factor value term constant string_lit string_op element

%%
number      : INTEGER               { $$.type = 0;
                                      $$.ival = $1; }
            | DOUBLE                { $$.type = 1;
                                      $$.dval = $1; }
            ;

factor      : number                { $$ = $1; }
            | '(' constant ')'      { $$ = $2; } 
            ;

value       : factor                { $$ = $1; }
            | value '^' factor      { doMath(&$$, $1, $3, '^'); }   
            ;

term        : value                 { $$ = $1; }
            | term '*' value        { doMath(&$$, $1, $3, '*'); }
            | term '/' value        { doMath(&$$, $1, $3, '/'); }
            | term '%' value        { doMath(&$$, $1, $3, '%'); }
            ;

constant    : term                  { $$ = $1; }
            | constant '+' term     { doMath(&$$, $1, $3, '+'); }
            | constant '-' term     { doMath(&$$, $1, $3, '-'); }
            ;

string_lit  : STRING LITERAL        { $$.type = 2; 
                                      $$.string = malloc(sizeof(strlen($1))+1);
                                      memcpy($$.string, $1, sizeof($1));        }
            ;

string_op   | string_lit                { $$ = $1; }
            | string_op '+' string_lit  { concat(&$$, $1, $3); }
            ;

variable    : string_op                 { $$ = $1; }
            | constant                  { $$ = $1; }
            | variable '+' string_op    { doMath(&$$, $1, $3, '+') };
            | variable '+' constant     { doMath(&$$, $1, $3, '+') };
            | variable '-' string_op    { doMath(&$$, $1, $3, '-') };
            | variable '-' constant     { doMath(&$$, $1, $3, '-') };
            | variable '*' string_op    { doMath(&$$, $1, $3, '*') };
            | variable '*' constant     { doMath(&$$, $1, $3, '*') };
            | variable '/' string_op    { doMath(&$$, $1, $3, '/') };
            | variable '/' constant     { doMath(&$$, $1, $3, '/') };
            | variable '%' string_op    { doMath(&$$, $1, $3, '%') };
            | variable '%' constant     { doMath(&$$, $1, $3, '%') };
            | variable '^' string_op    { doMath(&$$, $1, $3, '^') };
            | variable '^' constant     { doMath(&$$, $1, $3, '^') };
            | variable '>' string_op    { doMath(&$$, $1, $3, '>') };
            | variable '>' constant     { doMath(&$$, $1, $3, '>') };
            | variable '<' string_op    { doMath(&$$, $1, $3, '<') };
            | variable '<' constant     { doMath(&$$, $1, $3, '<') };
            | variable GT_EQ string_op  { doMath(&$$, $1, $3, '.') }; //>=
            | variable GT_EQ constant   { doMath(&$$, $1, $3, '.') }; 
            | variable LT_EQ string_op  { doMath(&$$, $1, $3, ',') }; //<=
            | variable LT_EQ constant   { doMath(&$$, $1, $3, ',') };
            ;
%%

我已经在“%type”行中声明了“string_op”。我不确定该怎么做。

1 个答案:

答案 0 :(得分:2)

错误消息可能应该说&#34; Unexpected |&#34;,因为string_op之后的预期是

bison产生奇怪错误消息的原因是bison lexer将标识符与后面的组合成一个类型为id_colon而不是identifier的标记。这样做是因为; 在规则的末尾是可选的,因此如果是一个令牌,则bison规则语法将是LR(2)。 (讽刺的,真的。)所以它期待一个id_colon,它意外地发现了一个identifier