2012-04-09 64 views
0

我有以下的语法解析器(这是一个小样本):Bison分析器不会前瞻令牌

expr: 
     ident assignop expr 
     { 
      $$ = new NAssignment(new NAssignmentIdentifier(*$1), $2, *$3); 
     } | 
     STAR expr %prec IDEREF 
     { 
      $$ = new NDereferenceOperator(*$2); 
     } | 
     STAR expr assignop expr %prec IDEREF 
     { 
      $$ = new NAssignment(new NAssignmentDereference(*$2), $3, *$4); 
     } | 
     ... ; 

... 

assignop: 
     ASSIGN_EQUAL | 
     ASSIGN_ADD | 
     ASSIGN_SUBTRACT | 
     ASSIGN_MULTIPLY | 
     ASSIGN_DIVIDE ; 

现在我试图解析以下任何行:

*0x8000 = 0x7000; 
*mem = 0x7000; 

但是,Bison不断看到“* mem”并减少了“STAR expr”规则,并且未执行预测以查看“STAR expr assignop ...”是否匹配。据我了解Bison,它应该做这个预测。我最接近的猜测是,%prec会关闭前瞻或类似的东西,但我不明白为什么会这样做(因为prec值相同)。

在这种情况下,我如何使它看起来超前?

编辑:

,它进入遇到当“明星EXPR”的状态是:

state 45 

    28 expr: STAR expr . 
    29  | STAR expr . assignop expr 
    35  | expr . binaryop expr 

    $default reduce using rule 28 (expr) 

    assignop go to state 81 
    binaryop go to state 79 

所以我不明白为什么它捡$默认情况下它可以挑选assignop(注在这种情况下,parser.y文件中规则的顺序不会影响它选择哪一个;我尝试在标准'STAR expr'之上重新排序assignop')。

回答

0

我结束了创建另一个规则“DEREF”像这样解决这个问题:

deref: 
     STAR ident 
     { 
      $$ = new NDereferenceOperator(*$<ident>2); 
     } | 
     STAR numeric 
     { 
      $$ = new NDereferenceOperator(*$2); 
     } | 
     STAR CURVED_OPEN expr CURVED_CLOSE 
     { 
      $$ = new NDereferenceOperator(*$3); 
     } | 
     deref assignop expr 
     { 
      if ($1->cType == "expression-dereference") // We can't accept NAssignments as the deref in this case. 
       $$ = new NAssignment(new NAssignmentDereference(((NDereferenceOperator*)$1)->expr), $2, *$3); 
      else 
       throw new CompilerException("Unable to apply dereferencing assignment operation to non-dereference operator based LHS."); 
     } ; 

在“expr的”用一个单一的“DEREF”更换两个规则。

0

如果IDREFASSIGN_EQUAL优先,ASSIGN_ADD等。特别是较高的,在这种情况下,与原解析器(优先级被应用于前)会出现这种情况,你有移位/减少expr: STAR expr规则和各种ASSIGN_ XXX之间的冲突令牌。优先规则解决了所有有利于减少的冲突。

该状态下的assignop是转到,而不是转移或减少,所以根本不进入前瞻或标记处理 - gotos只发生在某个标记移位后,然后减少到非有问题的终端。

+0

糟糕!我想我已经删除了这个问题,因为我已经解决了它。我现在更好地回答我的答案... – 2012-04-09 05:31:41