我正在学习如何使用树保姆,并制定语法来解析简单的谓词逻辑。很明显,我需要优先权来使否定~
比连接和断开(/
和/
(结合得更紧密。我认为我已经正确地应用了优先级,实际上是复制了文档中的示例。
语法如下:
module.exports = grammar({
name: 'Predicate_Calculus',
rules: {
// TODO: add the actual grammar rules
source_file: $ => repeat($._expression),
_expression: $ => choice($.identifier,
$._unary_expression,
$._binary_expression,
seq('(', $._expression, ')')),
_binary_expression: $ => choice(
$.and,
$.or
),
_unary_expression: $ => prec(2, choice(
$.not
)),
not: $ => seq('~', $._expression),
and: $ => prec.left(seq($._expression, "/\", $._expression)),
or: $ => prec.left(seq($._expression, "\/", $._expression)),
identifier: $ => /[a-z_]+/
}
});
然而,当我运行tree-sitter generate
时,我得到了这个错误:
╰─➤ tree-sitter generate
Unresolved conflict for symbol sequence:
'~' _expression • '/' …
Possible interpretations:
1: '~' (and _expression • '/' _expression) (precedence: 0, associativity: Left)
2: (not '~' _expression) • '/' …
Possible resolutions:
1: Specify a higher precedence in `and` than in the other rules.
2: Specify a higher precedence in `not` than in the other rules.
3: Specify a left or right associativity in `not`
4: Add a conflict for these rules: `not`, `and`
我相信我对prec(2 choice($.not))
所做的是选项2,但它在语法中似乎并不有效。我使用的是通过cargo
安装的tree-sitter
0.20.7。
好吧,在尝试了更多的排列之后,我发现将优先级指令移动到not
定义中可以解决这个问题。
_unary_expression: $ => choice(
$.not
),
not: $ => prec(2, seq('~', $._expression)),
从_unary_expression
中删除优先级,并将其移动到not
内部。