解析一个或多个具有有用错误的表达式

Parse one or more expressions with helpful errors

我正在使用 grako(python 的 PEG 解析器生成器库)来解析一种简单的声明性语言,其中文档可以包含一个或多个协议。

最初,我将文档的根规则写为:

document = {protocol}+ ;

这恰如其分地 returns 协议列表,但仅在第一个协议中存在语法错误时才提供有用的错误。否则,它会默默地丢弃无效协议及其后的所有内容。

我还尝试了一些变体:

document = protocol document | $ ;

但是,如果只有一个协议,这不会产生列表,也不会给出有用的错误消息,如果任何协议包含错误,则只说 no available options: (...) document

如何编写执行以下两项操作的规则?:

  1. 总是returns一个列表,即使只有一个协议
  2. 显示有关不成功匹配的有用错误消息,而不是仅仅说它是无效文档或默默地删除损坏的协议

这是解决方案:

document = {protocol ~ }+ $ ;

如果您不为解析器添加 $ 以查看文件结尾,则使用一个或多个 协议 解析将成功,即使有更需要解析。

添加 cut 表达式 (~) 使解析器提交到解析器中最接近的 option/choice 中解析的内容(闭包是一个X = a X|(); 的选项)。 cut 表达式在 protocol 解析的内容中将使错误消息更接近输入中预期的故障点。