Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parsing 将规则添加到TreeSetter LR1语法会更改优先级_Parsing_Lr1_Treesitter - Fatal编程技术网

Parsing 将规则添加到TreeSetter LR1语法会更改优先级

Parsing 将规则添加到TreeSetter LR1语法会更改优先级,parsing,lr1,treesitter,Parsing,Lr1,Treesitter,我试图在TreeSetter语法中获得正确的运算符优先级。Treesitter是一个LR1解析器生成器 我有一个简单的艺术语法,部分如下: multiply_expression: $ => prec.left(2, seq( $._expression, '*', $._expression, )), addition_expression: $ => prec.left(1, seq( $._expression, '+', $.

我试图在TreeSetter语法中获得正确的运算符优先级。Treesitter是一个LR1解析器生成器

我有一个简单的艺术语法,部分如下:

multiply_expression: $ => prec.left(2, seq(
    $._expression,
    '*',
    $._expression,
)),

addition_expression: $ => prec.left(1, seq(
    $._expression,
    '+',
    $._expression,
)),
这是正确的<代码>乘法表达式的优先级确实高于加法表达式

但是,当我添加中间规则时,优先级会发生变化:

_partial_multi: $ => seq(
    $._expression,
    '*',
),

multiply_expression: $ => prec.left(2, seq(
    $._partial_multi,
    $._expression,
)),
我将
$.expression“*”
移动到它自己的规则。对我来说,这似乎是一个等价的语法,我希望不会有任何变化。但是,随着此更改,优先级不再正确<代码>加法表达式保持不变,其优先级似乎高于乘法表达式


为什么引入额外步骤会改变优先级?这个问题有名字吗,或者在哪里可以找到更多的信息?在编写语法或解决优先级问题时,是否有需要遵循的规则或思考的方法?

以下是您的完整语法,以确保再现性:

module.exports = grammar({
  name: 'github_example',

  conflicts: $ => [],

  rules: {
    source_file: $ => $._expression,

    _expression: $ => choice(
      $.number,
      $.multiply_expression,
      $.addition_expression
    ),

    number: $ => /\d+/,

    _partial_multi: $ => seq(
        $._expression,
        '*',
    ),

    multiply_expression: $ => prec.left(2, seq(
        $._partial_multi,
        $._expression,
    )),

    addition_expression: $ => prec.left(1, seq(
        $._expression,
        '+',
        $._expression,
    )),
  }
});
您可以通过向
\u partial\u multi
规则添加优先级并从
multiply\u表达式中删除左关联优先级来解决此问题:

   _partial_multi: $ => prec(2, seq(
        $._expression,
        '*',
    )),

    multiply_expression: $ => seq(
        $._partial_multi,
        $._expression,
    ),
这里所做的是将乘法作为优先级为2的右联想运算符。这就是在语法中定义左或右关联性的方法,这些语法不会将其公开为原语。您可以通过如下方式将乘法设置为左关联:

    _partial_multi: $ => prec(2, seq(
        '*',
        $._expression,
    )),

    multiply_expression: $ => seq(
        $._expression,
        $._partial_multi,
    ),

实际上,您偶然发现了一件非常有趣的事情,即您不需要显式的语言构造来定义语法中的优先级和关联性!它们只是“语法糖”,使语法更容易读写。有关如何通过分解规则指定优先级和关联性的详细信息,请参见。您可以看到,纯粹通过语法结构来指定优先级和关联性是令人困惑的,除非您仔细考虑,否则几乎会从您期望的内容中反向读取!正如您还发现的,混合使用这两种方法(通过语言结构和语法结构指定优先级和关联性)可能会导致混淆行为。最好坚持使用其中一种方法。

我不知道TreeSetter如何重新排序和解决冲突的细节,但在我看来,您似乎还没有告诉解析器生成器如何解决涉及
\u partial\u multi
的冲突。你应该给那个作品分配一个优先权。而且,像往常一样,如果你在问题中加入了一个,你会更容易得到帮助。摘录不容易测试。说完这些,我模糊地试图填写一个测试文件,并应用了我在第一条评论中提出的建议。它似乎起作用了。正如您所报告的那样,原始测试(基于您的摘录)只是解析错误;不会发出歧义警告。(对于bison,它使用不同的优先级配置方式,会为您的语法发布冲突报告。)