::case的OCaml解析器



我在关联性方面遇到了问题。由于某些原因,my=运算符的优先级高于my::运算符

例如,如果我有

"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 }
.
.
.

看起来可能有多个表达式规则(expexp1exp2exp9(,在这种情况下,运算的优先级由这些规则的相互关系决定(哪个规则扩展到另一个规则(,而%left/%right声明在很大程度上是不相关的。

yacc优先级规则仅用于解决shift/reduce冲突,如果您的语法没有shift/reduce冲突(通过使用多个规则解决了歧义(,则优先级级别将不起作用。

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

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

最新更新