任何人都可以提供明确的解释和一些简单的示例,这些示例显示了此错误,显然与匹配时间捕获(CMT)有关?
我不明白我能找到的唯一提及,它是
http://lua-users.org/lists/lua-l/2013-06/msg00086.html
谢谢
,所以这个问题有点旧,但是它是第一个搜索结果之一。互联网上没有很多关于此事的事,而且可能并不明显。
错误消息有点误导,但是正在发生的事情 - 至少据我了解,在正式的钉术语中,有一个重复运算符应用于解析表达式,无法消耗输入。
或其他单词,LPEG检测到一个可以匹配的空字符串的循环,该循环永远无法完成。有一个纯LUA实现称为Lulpeg,它缺乏此特定的检查,如果您执行语法,则可以轻松进入无限循环。
我正在修补一些小玩具基本语言,并在上面有以下问题:
grammar = P{ "input",
input = V"block"^0 * -1,
block = V"expression"^0,
-- (define expression here)
}
有一个想法,即根输入是代码的可选块,并且一个块为零或更多表达式。当然,这是非常简单的,我忽略了空格处理和类似的事情。但是,当您称呼语法:匹配(")时会发生什么?
- 剩余的字符串:",输入。看看它是否匹配一个块。
- 剩余的字符串:",在街区。看看它是否与表达式匹配。
- 剩余的字符串:",表达。为了时间,假设它不匹配
- 剩余的字符串:",在街区。规则以零表达方式结束,没有消耗输入。
- 剩余的字符串:",输入。消耗一个块,检查更多块是否匹配。
- 剩余的字符串:",在街区。看看它是否与表达式匹配。
等等。由于v"块"匹配空字符串,因此输入可以找到一个无限数量的块来满足规则v" block"^0。在这种情况下,有两个好的解决方案:将输入设置为最多一个块,或者要求块至少一个表达式,而在任何地方都可以将其设置为 ^0。所以要么:
grammar = P{ "input", -- blocks can be empty, input contains one (empty or otherwise) block
input = V"block" * -1,
block = V"expression"^0,
-- (define expression here)
}
或:
grammar = P{ "input", -- blocks must be at least one expression, root can have one
input = V"block"^0 * -1,
block = V"expression"^1,
-- (define expression here)
}
在第一种情况下,一个空字符串将匹配一个块,该块可以满足输入规则。在第二个中,一个空字符串将失败块,实现零匹配块的输入规则。
我还不需要使用CMT,但是我相信发生的是LPEG的旧版本,即即使CMT调用中的规则可以匹配一个空字符串,该功能即将失败或消耗输入。最近的版本没有此假设。