将值作为规则的参数传递

时间:2015-01-05 09:21:24

标签: parsing ocaml lr menhir

在实现真实世界(TM)语言时,我经常会遇到这样的情况:

(* language Foo *)
type A = ... (* parsed by parse_A *)
type B = ... (* parsed by parse_B *)
type collection = { as : A list ; bs : B list }

(* parser ParseFoo.mly *)
parseA : ... { A ( ... ) }
parseB : ... { B ( ... ) }

parseCollectionElement : parseA { .. } | parseB { .. }

parseCollection : nonempty_list (parseCollectionElement) { ... }

显然(在函数式中),最好将部分解析的collection记录传递给parseAparseB的语义操作的每次调用,并相应地更新列表元素

甚至可以使用menhir,还是必须使用使用可变全局变量的丑陋黑客?

1 个答案:

答案 0 :(得分:1)

嗯,你在menhir / ocamlyacc语义行为中被允许做的事情非常有限。如果你发现这真的令人沮丧,你可以尝试类似parsec的解析器,例如mparser,允许您在规则中使用OCaml。

我对这类问题的个人理解是在解析器中保持最原始的水平,而不是试图定义任何复杂的东西,并在以后将解析器输出提升到更高的水平。

但是你的案子看起来很简单。在这里,您可以手动编写列表规则,而不是使用参数化的menhir规则,并在其语义规则中生成集合。 nonempty_list是一种语法糖,与大多数其他糖一样,在大多数情况下都有效,但总的来说不太通用。