解析器 - 转移/减少冲突

时间:2015-04-07 11:58:29

标签: bison yacc parser-generator

我的解析器出了问题,让我发疯,并想知道你们是否能够帮助我。

我有这套规则:

exp:        exp OP exp
    |       exp OSQUAREPAR exp CSQUAREPAR
    |       exp DOT LENGTH
    |       exp DOT ID OPAR expList CPAR
    |       READERS DOT INTREADER DOT READINT OPAR CPAR
    |       DIGIT
    |       TRUE
    |       FALSE
    |       ID
    |       THIS
    |       NEW INT OSQUAREPAR exp CSQUAREPAR 
    |       NEW ID OPAR CPAR
    |       EXCL exp    
    |       OPAR exp CPAR   
    ;

以下冲突:

  

规则28 exp - > exp OP exp

     

规则29 exp - > exp OSQUAREPAR exp CSQUAREPAR

     

规则30 exp - > exp DOT LENGTH

     

规则31 exp - > exp DOT ID OPAR expList CPAR

     

规则32 exp - > READERS DOT INTREADER DOT READINT OPAR CPAR

     

规则33 exp - > DIGIT

     

规则34 exp - > TRUE

     

规则35 exp - > FALSE

     

规则36 exp - > ID

     

规则37 exp - >这

     

规则38 exp - >新的INT OSQUAREPAR exp CSQUAREPAR

     

规则39 exp - >新ID OPAR CPAR

     

规则40 exp - > EXCL exp

     

规则41 exp - > OPAR exp CPAR

state 94

exp  ->  EXCL exp .   (rule 37)
exp2  ->  exp . OP exp   (rule 39)
exp2  ->  exp . OSQUAREPAR exp CSQUAREPAR   (rule 40)
exp2  ->  exp . DOT LENGTH   (rule 41)
exp2  ->  exp . DOT ID OPAR expList CPAR   (rule 42)

OSQUAREPAR    shift, and go to state 97
DOT   shift, and go to state 98
OP    shift, and go to state 99

OSQUAREPAR    [reduce using rule 37 (exp)]
DOT   [reduce using rule 37 (exp)]
OP    [reduce using rule 37 (exp)]
$default  reduce using rule 37 (exp)

如何解决这个问题?我已经检查了其他类似的问题,甚至尝试为EXCL添加优先级,就像其中一个答案所示,但无法解决这个问题。

感谢。

1 个答案:

答案 0 :(得分:2)

可能的方法示例(无冲突):

%token DIGIT FALSE ID INT INTREADER LENGTH NEW READERS READINT THIS TRUE

%left  '+' '-'
%left  '*' '/'
%left  UNARY

%%

exp:       unary
   |       exp '+' exp
   |       exp '-' exp
   |       exp '*' exp
   |       exp '/' exp
   ;

expList:    exp
       |    expList ',' exp
       ;

operand:    '(' exp ')'
       |    DIGIT
       |    TRUE
       |    FALSE
       |    ID
       |    THIS
       |    READERS '.' INTREADER '.' READINT '(' ')'
       |    NEW INT '[' exp ']' 
       |    NEW ID '(' ')'
       ;

primary:    operand
       |    primary '[' exp ']'
       |    primary '.' LENGTH
       |    primary '.' ID '(' expList ')'
       ;

unary:      primary
     |      '!' unary
     |      '+' unary
     |      '-' unary %prec UNARY
     ;