可能有人帮助我,我有这个规则:
e : T_NUM { $$ = mk_int($1);}
| 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);}
| e T_PLUS e { $$ = mk_app(mk_app(mk_op(PLUS),$1),$3);}
| e T_MINUS e { $$ = mk_app(mk_app(mk_op(MINUS),$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);env = push_rec_env($var,$$,env);} /*Définition de fonctions*/
| T_LET T_ID[x] T_EQUAL e[arg] T_IN e[exp] { $$ = mk_app(mk_fun($x,$exp),$arg); env = push_rec_env($x,$$,env);}/*Fonction IN*/
| e[exp] T_WHERE T_ID[x] T_EQUAL e[arg] { $$ = mk_app(mk_fun($x,$exp),$arg); env = push_rec_env($x,$$,env);}/*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);}
| '(' f_arg[fun] e[arg] ')' { $$ = mk_app($fun,$arg);}/*Exécution de fonctions à plusieurs variables*/
| '(' e ')' { $$ = $2;}/*Ignorer les parentheses inutiles*/
;
我的问题是在'('f_arg [fun] e [arg]')'我想删除语法周围的'()'但这会产生大量冲突,所以如果有人可以帮我一把如何在没有括号的情况下更改此语法 有关f_arg的信息:
f_arg :e {$$ = $1;}
|f_arg[fun] e[arg] {$$ = mk_app($fun,$arg);}
;
感谢所有
可以在
找到完整的代码https://github.com/WillianPaiva/project_AS
抱歉我的英文
答案 0 :(得分:1)
好吧,我没有尝试编译和测试它。但是,在删除'('
和)'
时,您似乎正在创建一个包含规则的循环。您说e->f_arg
然后f_arg->e
。显然这会产生冲突。
如果您将| '(' f_arg[fun] e[arg] ')'
替换为| e[arg] f_arg[fun]
,并将f_arg :e
替换为f_arg :
(空规则)。然后,您需要重新配置语法的所有操作,即每个规则前面的代码。
如果我的建议不起作用,您必须找到一种方法来删除e
和f_arg
之间的循环
答案 1 :(得分:1)
问题在于,对于所有二进制中缀和前缀oparators,未经修饰的函数应用程序是不明确的 - 如果a b + c
之类的输入被解析为(a b) + c
或a (b + c)
?由于功能应用程序中没有任何令牌,因此正常的yacc / bison优先级规则在没有额外帮助的情况下无法使用。
假设你想给函数应用程序赋予最高优先级(正常情况,我相信),你可以通过一些额外的工作来完成这项工作。
将以下优先规则添加到列表末尾(最高优先级):
%left FUNCTION_APPLICATION T_NUM T_ID '{' '('
制定你的职能规则:
| e[fun] e[arg] %prec FUNCTION_APPLICATION { $$ = mk_app($fun,$arg); }
取决于语法中的其他内容,您可能需要在优先级规则中添加更多标记和/或稍微重新排列。特别是,FIRST(e)中的每个标记都需要一个优先级,如果它对函数应用程序的优先级与其它用途的优先级不同,那么事情就不会起作用(因为每个标记只能有一个优先级)。只要函数应用程序的优先级高于其他所有函数,事情就应该是可解析的。