我将编写一个verilog(或vhdl)语言的解析器,并将对解析的数据进行大量操作(某种转换)。我打算解析真正的大文件(完整的Verilog设计,大到10K行),我最终会支持大部分的Verilog。我不介意输入,但每当我添加对其他规则的支持时,我都不想重写代码的任何部分。
在Haskell中,您会推荐哪个库?我知道Haskell并且之前使用过Happy(玩)。我觉得有可能使用Parsec来转换代码中的解析字符串(这是一个很好的加分)。我对uu-paringlib没有经验。
那么要解析verilog / VHDL的全语法,推荐其中一个?我主要担心的是我可以随心所欲地操纵解析数据的简易性和“正确性”。速度不是主要问题。
答案 0 :(得分:19)
我个人更喜欢Parsec在Alex的帮助下进行lexing。
我更喜欢Parsec而不是Happy,因为1)Parsec是一个库,而Happy是一个程序,如果你使用Happy,你会用另一种语言写,然后用Happy编译。 2)Parsec凭借其monadic接口为您提供了上下文相关的解析功能。您可以使用额外的状态进行上下文相关的解析,然后根据该状态进行检查和决定。或者只是查看一些解析后的值并决定下一个解析器等(如a <- parseSomething; if test a then ... do ...
)当您不需要任何上下文相关信息时,您可以简单地使用applicative样式并获得在YACC中实现的实现或类似的工具。
作为Parsec的缺点,你永远不会知道你的Parsec解析器是否包含左递归,并且你的解析器会在运行时卡住(因为Parsec基本上是一个自上而下的递归下降解析器)。你必须找到左递归并消除它们。 YACC风格的解析器可以为您提供一些静态保证和信息(如移位/减少冲突,未使用的终端等),这是Parsec无法获得的。
Alex强烈建议在两种情况下使用lexing(我认为如果你决定继续使用Happy ,你必须使用Alex)。因为即使您使用Parsec,它也真正简化了您的解析器实现,并且也捕获了大量错误(例如:将关键字解析为标识符是我在使用没有Alex的Parsec时所做的常见错误。这只是一个示例)。
您可以查看我在Alex + Parsec中实施的Lua parser这里是code to use Alex-generated tokens in Parsec。
编辑:感谢John L
进行更正。显然,您也可以使用Happy进行上下文相关的解析。此外,虽然建议使用快乐,但不需要Alex for lexing。