用于:: case的OCaml解析器

时间:2014-05-15 22:13:38

标签: ocaml yacc ocamlyacc

我在结社方面遇到麻烦。由于某种原因,my =运算符的优先级高于my :: operator

所以,例如,如果我有

  

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

.
.
.

2 个答案:

答案 0 :(得分:4)

看起来您可能有多个表达式规则(expexp1exp2,... exp9),在这种情况下,操作的优先级将被确定通过这些规则的相互关系(哪个规则扩展到其他规则),%left / %right声明在很大程度上无关紧要。

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

答案 1 :(得分:4)

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

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