解析器 - Shift/reduce 冲突
Parser - Shift/reduce conflict
我的解析器有问题,这让我发疯,想知道你们是否能帮助我。
我有这套规则:
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
;
与以下冲突:
rule 28 exp -> exp OP exp
rule 29 exp -> exp OSQUAREPAR exp CSQUAREPAR
rule 30 exp -> exp DOT LENGTH
rule 31 exp -> exp DOT ID OPAR expList CPAR
rule 32 exp -> READERS DOT INTREADER DOT READINT OPAR CPAR
rule 33 exp -> DIGIT
rule 34 exp -> TRUE
rule 35 exp -> FALSE
rule 36 exp -> ID
rule 37 exp -> THIS
rule 38 exp -> NEW INT OSQUAREPAR exp CSQUAREPAR
rule 39 exp -> NEW ID OPAR CPAR
rule 40 exp -> EXCL exp
rule 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 添加优先级,但无法解决这个问题。
谢谢。
一个可能的方法示例(无冲突):
%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
;
我的解析器有问题,这让我发疯,想知道你们是否能帮助我。
我有这套规则:
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
;
与以下冲突:
rule 28 exp -> exp OP exp
rule 29 exp -> exp OSQUAREPAR exp CSQUAREPAR
rule 30 exp -> exp DOT LENGTH
rule 31 exp -> exp DOT ID OPAR expList CPAR
rule 32 exp -> READERS DOT INTREADER DOT READINT OPAR CPAR
rule 33 exp -> DIGIT
rule 34 exp -> TRUE
rule 35 exp -> FALSE
rule 36 exp -> ID
rule 37 exp -> THIS
rule 38 exp -> NEW INT OSQUAREPAR exp CSQUAREPAR
rule 39 exp -> NEW ID OPAR CPAR
rule 40 exp -> EXCL exp
rule 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 添加优先级,但无法解决这个问题。
谢谢。
一个可能的方法示例(无冲突):
%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
;