语法无法被解析器识别 - 如何阅读yydebug?

时间:2014-04-29 15:15:21

标签: bison yacc

你好,我正在研究以下语法:

 e   : e T_MINUS e                                              { $$ = mk_app(mk_app(mk_op(MINUS),$1),$3);}
    | T_NUM                            { $$ = mk_int($1);}
    | T_MINUS e                        { $$ = mk_app(mk_app(mk_op(MULT),mk_int(-1)),$2);}
    | T_POP e[l]                           { $$ = mk_app(mk_op(POP),$l);}
    | T_NEXT e[l]                          { $$ = mk_app(mk_op(NEXT),$l);}
    |'{' e[x] ',' e[y] '}'                     { $$ = mk_point($x,$y);} 
    | T_BEZIER '(' e[p1] ',' e[p2] ',' e[p3] ',' e[p4] ')' { $$ = mk_bezier($p1,mk_bezier($p2,mk_bezier($p3,mk_bezier($p4,NULL))));}
    | T_CIRCLE '(' e[c] ',' e[r] ')'                       { $$ = mk_circle($c,$r);}     
    | T_TRANS '(' e[fig] ',' e[vect] ')'                   { $$ = mk_app(mk_app(mk_op(TRANS),$fig),$vect);}    
    | e T_PATH e                                           { $$ = mk_path($1,mk_path($3,NULL));}
    | e T_PLUS e                                           { $$ = mk_app(mk_app(mk_op(PLUS),$1),$3);}
    | e T_DIV e                                            { $$ = mk_app(mk_app(mk_op(DIV),$1),$3);}
    | e T_MULT e                                           { $$ = mk_app(mk_app(mk_op(MULT),$1),$3);}
    | e T_LEQ e                                            { $$ = mk_app(mk_app(mk_op(LEQ),$1),$3) ;}
    | e T_LE e                                             { $$ = mk_app(mk_app(mk_op(LE),$1),$3) ;}
    | e T_GEQ e                                            { $$ = mk_app(mk_app(mk_op(GEQ),$1),$3) ;}
    | e T_GE e                                             { $$ = mk_app(mk_app(mk_op(GE),$1),$3) ;}
    | e T_OR e                                             { $$ = mk_app(mk_app(mk_op(OR),$1),$3) ;}
    | e T_AND e                                            { $$ = mk_app(mk_app(mk_op(AND),$1),$3) ;}
    | T_ID                                                 { $$ = mk_id($1);}/*Reconnaissance d'identificateurs et de variables*/
    | e T_EQ e                                             { $$ = mk_app(mk_app(mk_op(EQ),$1),$3) ;}
    | T_NOT e[expr]                                        { $$ = mk_app(mk_op(NOT),$expr) ;}
    | T_FUN T_ID[var] arg_list[expr]                       { $$ = mk_fun($var,$expr);} /*Définition de fonctions*/
    | T_LET T_ID[x] T_EQUAL e[arg] T_IN e[exp]             { $$ = mk_app(mk_fun($x,$exp),$arg); }/*Fonction IN*/
    | e[exp] T_WHERE T_ID[x] T_EQUAL e[arg]                { $$ = mk_app(mk_fun($x,$exp),$arg); }/*Fonction WHERE*/
    | T_IF e[cond] T_THEN e[then_br] T_ELSE e[else_br]     { $$ = mk_cond($cond, $then_br, $else_br) ;}
    | '[' list[l] ']'                                      { $$ = $l;}/*OP sur Listes*/
    | e[exp] T_PUSH e[l]                                   { $$ = mk_app(mk_app(mk_op(PUSH),$exp),$l);}
    |  e[fun] e[arg] %prec FUNCTION_APPLICATION            { $$ = mk_app($fun,$arg);}/*Exécution de fonctions à plusieurs variables*/
    | '(' e ')'                                            { $$ = $2;}/*Ignorer les parentheses inutiles*/
    ;

当我使用list wich时:

list  : e[ex]               {$$ = mk_cell($ex,mk_nil());}
      | e[ex] ',' list[l]               {$$ = mk_cell($ex,$l);}
      |/*empty*/                    {$$ = mk_nil();}
      ;

paser识别列表但如果我使用'e'T_ID则返回语法错误

例如:

[1,2,3]确定

[1 + 2,2-5] ok

但如果我有:

a = 2

b = 3

并列出如下列表:

[A,B]

它返回语法错误

我想了解的是为什么不考虑表达式T_ID

提前感谢所有

EDIT: debug result :

        Reading a token: [a,b];
    Next token is token T_ID ()
    Shifting token T_ID ()
    Entering state 4
    Reducing stack by rule 26 (line 116):
       $1 = token T_ID ()
    -> $$ = nterm e ()
    Stack now 0 1
    Entering state 21
    Reading a token: Next token is token ',' ()
    syntax error
    Error: popping nterm e ()
    Stack now 0 1
    Error: popping nterm s ()
    Stack now 0
    Cleanup: discarding lookahead token ',' ()
    Stack now 0

编辑2:

不,这不是完整的调试,但是例如当我们使用'{' e ',' e '}'时 它确实首先移动'{'标记,但是'''它没有,我无法找到原因 我确实重新检查了flex规则的解析器:

[(),\[\]{}]         {return yytext[0];}

但没有任何反应,对于输出报告,因为它在这里是一个很长的链接:

parser.output

1 个答案:

答案 0 :(得分:0)

好的,我发现错误的原因是我不理解弹性规则:

[a-zA-z]+    {yylval.id = strdup (yytext); return T_ID;}

正在回归" [a"作为一个标记一旦它应该返回2个不同的标记一次规则:

[(),\[\]{}]         {return yytext[0];}

来吧。  改变规则

[a-zA-z]+    {yylval.id = strdup (yytext); return T_ID;}

代表

[[:alpha:]]+    {yylval.id = strdup (yytext); return T_ID;}

解决问题