问题描述
我正在尝试使用标识符和文字来解析语言。
b
b""
这里的 b
是一个标识符,而 b""
是一个文字(也可能是例如 b"foo"
)。
我有以下简化语法:
module.exports = grammar({
name: 'foo',rules: {
file: $ => repeat(choice(
$.ident,$.literal,)),ident: _ => /[a-z]/,literal: _ => seq('b',/\"[a-z]*\"/),},});
这会产生以下匹配状态:
(file [0,0] - [2,0]
(ERROR [0,0] - [0,1])
(literal [1,0] - [1,3]))
foo.bar 0 ms (ERROR [0,1])
即,我能够解析像 b""
这样的构造,但是 ident
的匹配器进入错误分支并且无法恢复。
我已经尝试过 token
没有成功。这里缺少什么?
解决方法
正如@maxbrunsfeld 在 GH 讨论中指出的那样,token
确实是这个玩具示例的答案。
通过以下更改,这个玩具示例确实有效:
- literal: _ => seq('b',/\"[a-z]*\"/),+ literal: _ => token(seq('b',/\"[a-z]*\"/)),
(file [0,0] - [2,0]
(ident [0,0] - [0,1])
(literal [1,0] - [1,3]))
如果 literal
的引用部分的匹配器变得更复杂,这会像预期的那样遇到非终端的常见问题,但这是 token
的一个特性,而不是我发布的示例,例如,
ident: _ => /[a-z]/,literal: $ => token(seq('b',$.ident)),// WRONG.
Error processing rule literal
Details:
Grammar error: Unexpected rule Symbol(Symbol { kind: NonTerminal,index: 1 })