你好,我正在研究以下语法:
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];}
但没有任何反应,对于输出报告,因为它在这里是一个很长的链接:
答案 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;}
解决问题