TreeSitter优先级未生效:谓词逻辑语法解析冲突求助
TreeSitter谓词逻辑语法优先级冲突解决
在实现简单谓词逻辑的TreeSitter语法时,需要让否定运算符~的绑定优先级高于合取/\与析取\/,但按现有方式设置优先级后,执行tree-sitter generate时出现解析冲突错误。
原语法代码
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 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`
问题原因
你之前给_unary_expression添加prec(2)的方式不生效,因为TreeSitter的优先级设置需要直接作用在具体产生式规则上,而不是包裹规则的choice容器。当前not规则本身没有优先级标记,导致解析器无法识别它和二元运算符的优先级关系。
修复方案
将优先级直接绑定到not规则上,同时明确二元运算符的优先级数值低于not,并给单目否定运算符设置右结合性(符合逻辑运算的常规习惯):
module.exports = grammar({ name: 'Predicate_Calculus', rules: { source_file: $ => repeat($._expression), _expression: $ => choice( $.identifier, $.not, $.and, $.or, seq('(', $._expression, ')') ), // 移除多余的_unary_expression和_binary_expression中间层,简化结构 not: $ => prec.right(2, seq('~', $._expression)), and: $ => prec.left(1, seq($._expression, "/\\", $._expression)), or: $ => prec.left(1, seq($._expression, "\\/", $._expression)), identifier: $ => /[a-z_]+/ } });
关键修改点
- 直接给not规则加优先级:用
prec.right(2)修饰not的产生式,2代表优先级高于二元运算符的1,right确保嵌套否定(如~~a)被解析为~(~a),符合逻辑运算习惯。 - 明确二元运算符优先级:给
and和or设置prec.left(1),数值低于not的2,明确优先级层级。 - 简化语法结构:移除
_unary_expression和_binary_expression中间规则,直接在_expression中列出所有表达式类型,让优先级关系更清晰。
修改后执行tree-sitter generate即可解决冲突,解析~a /\ b时会正确优先绑定~a,再和b进行合取运算。
内容的提问来源于stack exchange,提问作者asm
相关产品推荐
相关产品推荐

