2

我在关联性方面遇到了麻烦。出于某种原因,我的 = 运算符的优先级高于我的 :: 运算符

例如,如果我有

“1::[] = []”

作为一个字符串,我会得到

1 = []::[]

作为我的表达,而不是

[1] = []

如果我的字符串是“1::2::[] = []”

我以为我会把它解析成 exp1 EQ exp2,然后从那时起它会解析 exp1 和 exp2。但它被解析为 exp1 COLONCOLON exp2

.
.
.

%nonassoc LET FUN IF
%left OR
%left AND
%left EQ NE LT LE
%right SEMI COLONCOLON
%left PLUS MINUS
%left MUL DIV
%left APP

.
.
.

exp4:
    | exp4 EQ exp9                { Bin ($1,Eq,$3) }
    | exp4 NE exp9                { Bin ($1,Ne,$3) }
    | exp4 LT exp9                { Bin ($1,Lt,$3) }
    | exp4 LE exp9                { Bin ($1,Le,$3) }
    | exp9                        { $1 }

exp9:
    | exp COLONCOLON exp9         { Bin ($1,Cons,$3) }
    | inner                       { $1 }

.
.
.
4

2 回答 2

4

规则不仅仅像函数一样被应用,所以你不能在一组规则中重构你的语法,至少使用ocamlyacc. 您可以尝试使用menhir, 允许通过内联规则(%inline指令)进行此类重构。

要启用menhir它,您需要安装它,并将一个选项传递-use-menhirocamlbuild,如果您正在使用它。

于 2014-05-16T03:05:08.033 回答
4

看起来您可能有多个表达式规则(exp, exp1, exp2, ... exp9),在这种情况下,操作的优先级由这些规则的相互关系决定(哪个规则扩展到另一个规则),并且%left/%right声明在很大程度上是不相关的.

yacc 优先级规则仅用于解决移位/归约冲突,如果您的语法没有移位/归约冲突(通过使用多个规则解决了歧义),则优先级将无效。

于 2014-05-16T02:26:31.413 回答