【发布时间】:2021-07-12 05:46:24
【问题描述】:
我正在尝试使 Treesitter 语法中的运算符优先级正确。 Treesitter 是一个 LR1 解析器生成器。
我有一个简单的算术语法,部分看起来像这样:
multiply_expression: $ => prec.left(2, seq(
$._expression,
'*',
$._expression,
)),
addition_expression: $ => prec.left(1, seq(
$._expression,
'+',
$._expression,
)),
这可以正常工作。 multiply_expression 的优先级确实高于 addition_expression。
但是,当我添加中间规则时,优先级会发生变化:
_partial_multi: $ => seq(
$._expression,
'*',
),
multiply_expression: $ => prec.left(2, seq(
$._partial_multi,
$._expression,
)),
我将$.expression, '*' 移到了自己的规则中。对我来说,这似乎是一个等效的语法,我预计不会有任何变化。但是,随着这种变化,优先级不再正确。保持不变的addition_expression 的优先级似乎高于multiply_expression。
为什么引入额外的步骤会改变优先级?是否有此问题的名称,或者我在哪里可以找到有关它的更多信息?在编写语法或修复优先级问题时,是否有要遵循的规则或思考方式?
【问题讨论】:
-
我不知道treesitter如何重新定位和解决冲突的细节,但在我看来你还没有告诉解析器生成器如何解决涉及
_partial_multi的冲突。您应该为该产生式分配优先级。 -
另外,像往常一样,如果您在问题中包含minimal reproducible example,会更容易为您提供帮助。提取物不容易测试。
-
说了这么多,我模糊地尝试填写一个测试文件,并应用了我在第一条评论中提出的建议。它似乎工作。正如您所报告的,原始测试(基于您的摘录)只是解析不正确;不会发出歧义警告。 (对于使用不同配置优先级的方式的 bison,会为您的语法发出冲突报告。)
标签: parsing lr1 treesitter