2015-02-10 40 views
0

我现在坐在一个问题面前多个小时,看起来相当简单但解决不了问题,但我不能得到它:/jison规则优先顺序不起作用?

我在jison中定义了一个类似javascript的小语言。问题是参数规则和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

那么有没有办法解决这个问题?我当然是用%左右,%右,%assoc命令和%的优先级已经尝试过,但它没有工作(或我做错了什么?

+0

没有“作业”生产。如果你的意思是'AssignmentStatement',那么我看不到任何'AssignmentStatement'和'Parameter'都是可行的。你究竟看到了什么将你引向你的问题描述? – rici 2015-02-10 21:26:26

+0

是啊对不起我补充AssignStatement 问题是,如果我例如添加一个throw语句到第二个参数规则,它到达这个语句,所以它解析'i = 5;'作为一个参数,而不是一个AssingStatement 我更新了问题 – M4GNV5 2015-02-10 21:58:17

+0

'5'减少到'Parameter'预期;它与'我'无关。我试图在一个答案中解释。 – rici 2015-02-10 22:07:37

回答

2

你误解自下而上的解析器的流量控制。

操作当相关产量下调被执行(即充分认可),这将不会发生,直到所有生产非终端已经降低之后

AssignmentStatement生产:

AssignStatement 
    : CHAR_SEQUENCE AssignmentOperator Parameter ';' 

所以之前其相关的acti可以执行,必须执行AssignmentOperatorParameter的生产。在这种情况下,Parameter5匹配。

+0

当我用'throw $ 1'替换throw语句时,它给了''''而不是'5'此外5应该是NUMBER> InlineVariable>参数,所以你的答案不是很有帮助:/ 反正我定义FunctionDefinition为'FUNCTION CHAR_SQUENCE '('CHAR_SQUENCE ParameterList')'Block'and ParameterList as'','CHAR_SQUENCE ParameterList'它可能不是最好的解决方案,但它的解决方法至少可以工作^^ – M4GNV5 2015-02-11 18:44:38

+0

@ M4GNV5:好的,我很高兴你找到了一个解决方法。在给定输入'i = 5;'的'AssignmentStatement'中,我仍然没有在你发布的代码片段中看到任何'Parameter'可以匹配'i'的代码片段。如果这只是输入的一部分,它可能适用于你不显示的其他语法部分。我没有看到任何其他类型的可能以'parameter'开始的语句。 – rici 2015-02-11 19:11:18

+0

@ M4GNV5此外,我从你的要点中提取了语法,修正了词法分析器识别'<'和其他单个字符标记,修复了缺少的'AdditionalParameter'非终端(通过将其更改为'ParameterList','',删除了所有的动作,然后成功(并且正确地)解析了'i = 5;'和'if(i> 7)i = 5;'在'Parameter'规则中使用'alert'来表示减少。是不行的,你需要更清楚你的例子,你的语法和你的测试。 – rici 2015-02-11 20:12:54