0

我正在尝试使用标识符和文字解析语言。

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, 0] - [0, 1])

即,我能够解析类似的结构b"",但匹配器ident进入错误分支并且无法恢复。

我试过token没有成功。这里缺少什么?

4

1 回答 1

0

正如@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 })
于 2020-12-23T09:26:31.520 回答