转移/减少与嵌套列表的冲突

时间:2017-08-11 16:13:23

标签: ocaml menhir

我一直在努力完成“ML中的现代编译器实现”,将SML转换为OCaml。本书定义了一种名为Tiger的语言,它具有let ... in ... end语法,用于在给定表达式的范围内声明类型,变量和函数。此外,应将相同类型的相邻声明组合在一起以允许相互递归。

我试图通过以下语法片段代表这是Menhir:

%right FUNCTION TYPE

.
.
.

decs: l = list(dec) { l }

dec:
  | l = nonempty_list(tydec) { A.TypeDec l }
  | v = vardec { v }
  | l = nonempty_list(fundec) { A.FunctionDec l }

tydec:
  | TYPE; name = ID; EQUAL; ty = ty {
      A.{
        type_name = Symbol.symbol name;
        type_ty = ty;
        type_pos = Position.make $startpos $endpos
      }
    }

有了这个,我得到了一个转变/减少冲突,但是Menhir以我想要的方式解决了它。我希望nonempty_list(typec)贪婪,以便将相邻的TYPE声明组合在一起。即,在Menhir解决冲突的情况下,我生成的AST看起来像:

(LetExp
  (decs
    ((TypeDec
      (((type_name (my_type)) (type_ty (NameTy (int))))
       ((type_name (my_type2)) (type_ty (NameTy (string))))
    ))))
  (body (SeqExp ())))

我想摆脱警告,但我无法像Menhir一样解决冲突。我尝试使用%inline tydec,这确实会使警告消失,但TYPE的转变并未按照我的预期应用。相反,优先考虑decs中的列表,产生一个如下所示的AST:

(LetExp
  (decs
    ((TypeDec
      (((type_name (my_type)) (type_ty (NameTy (int))))))
     (TypeDec
      (((type_name (my_type2)) (type_ty (NameTy (string)))
  )))))
  (body (SeqExp ())))

我也试过明确设定优先权,但是Menhir警告我这是一个无用的宣言。

我确信我错过了一些基本的东西。给出产生列表列表的产品,如何让内部列表变得贪婪?

0 个答案:

没有答案