【问题标题】:jison rule precedence doesnt work?jison 规则优先级不起作用?
【发布时间】:2015-02-10 20:27:00
【问题描述】:

我现在要面对一个似乎很容易解决但我无法解决的问题:/

我正在 jison 中定义一种类似 javascript 的小型语言。问题是 Parameter 规则和 AssignStatement 规则都(可以)以 CHAR_SEQUENCE 开头,并且它总是选择参数规则。例如。即使代码是a = 5;,它也会到达throw "reached parameter";,所以它似乎将a 解析为参数而不是a = 5; 作为AssignStatement

我语法的相关部分:

Parameter
    : InlineVariable
        { $$ = $1; }
    | CHAR_SEQUENCE
        { throw "reached parameter"; checkUndefined($1, @1); $$ = vars[$1]; }
    ;

InlineVariable
    : NUMBER
        { $$ = new Runtime.Integer(parseInt($1)); }
    | '"' CHAR_SEQUENCE '"'
        { $$ = new Runtime.String($2); }
    | FUNCTION '(' ParameterList ')' Statement
        { $$ = new Container($5); }
    ;

AssignStatement
    : CHAR_SEQUENCE AssignmentOperator Parameter ';'
        {
            $$ = function()
            {
                if((typeof vars[$1] == 'undefined' && $3 instanceof Runtime.Integer) || (vars[$1] instanceof Container && $3 instanceof Runtime.Integer))
                    vars[$1] = new Runtime.Integer(0, $1);
                else if(typeof vars[$1] == 'undefined' || (vars[$1] instanceof Container && !($3 instanceof Container)))
                    vars[$1] = $3.constructor.call();

                $2(vars[$1], vars[$3]);
            }
        }
    | CHAR_SEQUENCE SingleAssignmentOperator ';'
        {
            $$ = function()
            {
                if(typeof vars[$1] == 'undefined')
                    vars[$1] = new Runtime.Integer(0, $1);

                $2(vars[$1]);
            };
        }
    ;

我把完整的语法贴在https://gist.github.com/M4GNV5/36c2550946c1a1f6ec91

那么有没有办法解决这个问题呢?我当然已经尝试过使用 %left、%right、%assoc 和 %precedence 但它没有用(或者我做错了什么?

【问题讨论】:

  • 没有Assignment 生产。如果您的意思是AssignmentStatement,那么我看不到任何地方AssignmentStatementParameter 都是可行的。您究竟观察到什么导致您提出问题描述?
  • 是的,对不起,我提到了 AssignStatement 问题是,如果我例如将 throw 语句添加到第二个 Parameter 规则它到达此语句,因此它将 i = 5;i 解析为 Parameter 而不是 AssingStatement 我更新了问题
  • 预计5 减少到Parameter;它与i 无关。我试图在答案中解释。

标签: javascript grammar operator-precedence jison


【解决方案1】:

您误解了自下而上解析器中的流控制。

当相关的产生式减少(即完全识别)时执行操作,直到产生式中的所有非终端都被减少后才会发生。

AssignmentStatement 的产生是:

AssignStatement
    : CHAR_SEQUENCE AssignmentOperator Parameter ';'

因此,在执行相关操作之前,必须执行 AssignmentOperatorParameter 的产生式。在这种情况下,Parameter5 匹配。

【讨论】:

  • 当我用 throw $1 替换 throw 语句时,它给了我 a 而不是 5 此外 5 应该是 NUMBER>InlineVariable>Parameter 所以你的答案不是很有帮助:/无论如何我定义了 FunctionDefinition作为FUNCTION CHAR_SQUENCE '(' CHAR_SQUENCE ParameterList ')' Block 和 ParameterList 作为',' CHAR_SQUENCE ParameterList 它可能不是最好的解决方案,但它的解决方法至少......有效 ^^
  • @M4GNV5:好的,很高兴你找到了解决方法。在给定输入i = 5; 的情况下,我仍然没有在您发布的sn-p 中看到Parameter 可以匹配AssignmentStatement 中的i 的任何内容。如果这只是输入的一部分,它可能适用于您未显示的语法的其他部分。我没有看到任何其他可能以parameter 开头的声明。
  • @M4GNV5 此外,我从您的要点中获取了语法,修复了词法分析器以识别 < 和其他一些单字符标记,修复了缺少的 AdditionalParameter 非终端(通过将其更改为ParameterList ',',删除所有操作,然后成功(并且正确地)解析 i = 5;if (i > 7) i = 5;Parameter 规则中使用 alert 来表示减少。所以如果有什么不工作,你会需要更清楚地了解您的示例、语法和测试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-16
  • 1970-01-01
  • 1970-01-01
  • 2018-12-15
  • 1970-01-01
相关资源
最近更新 更多