我已经看过两种解析方法:
使用happy
之类的解析器生成器。这允许您在BNF中指定语言,而不用担心解析的复杂性。但是,由于它是预处理器,因此您必须以文本方式编写整个解析树。
直接使用megaparsec
之类的解析器。使用这种方法,您可以直接访问代码,这样您就可以以编程方式生成解析器,但是您还没有获得带有优先注释等的快乐简单BNF规范的便利性。此外,打印输出似乎并非易事一个BNF树,用于解析代码中的文档,除非在构建过程中考虑这一点。
我想做的是这样的事情:
我想要这样做的原因是我正在处理的语法已经变得非常大并且有很多重复,因为它的许多结构与其他结构相似但略有不同。如果能够以编程方式生成而不是直接修改快乐的BNF规范,它将改善维护工作,但我不必从头开发自己的解析器。
这里有关于好方法的任何想法。如果我能够生成一个数据结构并将其强制转换为happy
(因为它可能在解析BNF提要后生成它自己的内部结构)会很好,但是happy
没有&# 39;似乎有一个库接口。
我想我可以生成引人入胜的BNF,然后将它提供给快乐,但这似乎是一个来回转换的混乱过程。更清洁的方法会更好。甚至可能是parsec
或megaparsec
的BNF样式扩展?
答案 0 :(得分:1)
最简单的做法是创建一些表示相关语法的数据类型,然后使用一些解析器组合器将其转换为解析器(运行时)"编译"步。不幸的是,大多数解析器组合器的效率和/或灵活性(在某些方面)都低于解析器生成器,因此这将是一个最小的公分母方法。也就是说,grammar-combinators库可能很有用,但它似乎没有得到维护。
有些库可以在运行时生成解析器。我刚才发现的一个是Grempa,它似乎没有被维护,但这可能不是问题。另一种选择(由同一个制作Grempa但保持不变的人)是Earley,由于Earley解析器的制作方式,有一个明确的语法被处理成解析器是有意义的。 Earley解析当然是灵活的,但可能会为你(或者可能不是)制服。