使用解析器组合器的原因是什么?

4
我可以帮您进行翻译。以下是关于在Haskell中使用解析器组合的方法,作者给出了下面的解析器组合器示例:

我正在研究以下方法,用于在Haskell中使用解析器组合器。作者举了解析器组合器的以下示例:

windSpeed :: String -> Maybe Int
windSpeed windInfo =
    parseMaybe windSpeedParser windInfo

windSpeedParser :: ReadP Int
windSpeedParser = do
    direction <- numbers 3
    speed <- numbers 2 <|> numbers 3
    unit <- string "KT" <|> string "MPS"
    return speed

作者提出采用这种方法的原因如下:
  • 易于阅读(我同意这一点)
  • 格式类似于规范,即解析器本身基本上是对其解析的描述(我同意这一点)

我不禁感觉自己错过了选择解析器组合子的一些原因。可能是使用Haskell带来的一些好处,例如编译时的保证、消除运行时错误。或者在开始解析DSL和使用自由单子时带来的一些后续好处。

我的问题是:使用解析器组合器的原因是什么?

1
因为数据往往是按层次结构组织的,所以您可以编写一个解析器来解析某个子元素,然后构建一系列解析器,每个解析器都完成谜题的一部分。例如,对于 XML 解析器,首先编写一个解析属性值的解析器,然后使用前面的解析器编写一个解析 key="value" 的解析器,然后重复该解析器以解析任意数量的键/值对,然后解析标签,然后解析标签层次结构等。 - Willem Van Onsem
1
我想强调的是,你可以重复使用库函数,并且不像基于BNF的方法那样受到上下文无关语法的限制。 - gallais
谢谢,您能否将其扩展成一个答案? - hawkeye
1
我认为你可以在这里找到答案:https://softwareengineering.stackexchange.com/questions/338665/when-to-use-a-parser-combinator-when-to-use-a-parser-generator - Shersh
1个回答

2

我认为使用解析器组合有几个好处:

  • 解析器组合是手写自顶向下解析器的一种泛化方法。在手写解析器的情况下,可以使用解析器组合来抽象出常见模式。
  • 与解析器生成器不同,解析器组合可能是“动态”的,在运行时允许进行决策。如果语言的语法可以根据输入重新定义,则此方面可能很有用。
  • 解析器是一等对象。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接