Bison 对没有端子、只有非端子的规则使用yacc优先级

Bison 对没有端子、只有非端子的规则使用yacc优先级,bison,yacc,Bison,Yacc,有人能帮我一下吗?我有一条规则: 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)

有人能帮我一下吗?我有一条规则:

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_参数的信息:

f_arg :e                                                            {$$ = $1;}
  |f_arg[fun] e[arg]                                            {$$ = mk_app($fun,$arg);}
  ;
谢谢大家

完整代码可在以下位置找到:


很抱歉我的英语

嗯,我还没有试着编译和测试它。但是当删除
(“
)”
时,看起来您正在使用规则创建一个循环。你是说
e->f_-arg
然后
f_-arg->e
。显然,这会造成冲突

如果您将
|'('f|arg[fun]e[arg]')
替换为
|e[arg]f|arg[fun]
,并将
f|arg:e
替换为
f|arg:
(空规则)。然后,您需要重新配置语法的所有操作,以及每个规则前面的代码


如果我的建议不起作用,您必须找到一种方法来消除
e
f_arg
之间的循环。问题是,对于所有二进制中缀和前缀运算器,未加修饰的函数应用程序都是不明确的——像
ab+c
这样的输入应该被解析为
(ab)+c
a(b+c)
?由于函数应用程序中不涉及令牌,因此如果没有额外的帮助,正常的yacc/bison优先规则将不适用于它

假设您希望赋予函数应用程序最高的优先级(我相信这是正常情况),您可以通过一些额外的工作来完成这项工作

将以下优先级规则添加到列表末尾(最高优先级):

制定你的函数规则:

| e[fun] e[arg] %prec FUNCTION_APPLICATION { $$ = mk_app($fun,$arg); }

根据语法中其他地方的内容,您可能需要向优先规则中添加更多标记和/或稍微重新排列。特别是,FIRST(e)中的每个标记都需要一个优先级,如果函数应用程序的优先级不同于其他用途的优先级,那么事情就不会起作用(因为每个标记只能有一个优先级)。只要函数应用程序的优先级高于其他任何东西,事情就应该是可以解决的。

这主要不起作用,因为f_arg和e是相同的类型,基本上我要做的是识别n“e”的序列。e和f_arg之间的循环是我找到的最好的方法,不管怎样,如果它不起作用,谢谢。你应该用另一个名字把所有的“e”规则加倍。然后将f_arg规则指向这个新规则。不太好看,但这是在其他方面没有冲突的唯一方法。使用您的解决方案,它在运行程序时确实有效。问题我得到了63个新的轮班减少问题,我将尝试自己解决这些问题,一旦目标是学习,但如果问得不多,我不了解%prec FUNCTION\u应用程序,具体问题是什么函数应用程序,因为我没有具有此名称的令牌
函数应用程序
是一个“假”(不存在)令牌,仅用于设置函数应用程序规则的优先级(不包含任何令牌)
%prec
是一个特殊指令,可应用于规则,手动将其优先级设置为其他某个标记的优先级。移位/减少冲突可能来自第一个(e)中需要优先级的某个标记。。。。
| e[fun] e[arg] %prec FUNCTION_APPLICATION { $$ = mk_app($fun,$arg); }