2017-02-16 14 views
1

Appel의 "Modern Compiler Implementation in ML"책에서 Tiger Parser를 생성하는 Ch3 프로그래밍 연습을 진행합니다. 내 tiger.grm 파일은 here입니다. 진단하려고하는 오류는 단항 및 2 진 빼기 연산자에 대한 규칙에서 발생하는 줄이기 충돌 감소입니다. 내가 MINUS보다 우선 순위를 가진 단항 정의 및 %prec를 사용하여 내 규칙에서 명시 적으로 설정 한ML-Yacc Tiger Parser 오류 줄이기/줄이기

error: state 128: reduce/reduce conflict between rule 48 and rule 46 on OR 
error: state 128: reduce/reduce conflict between rule 48 and rule 46 on AND 
error: state 128: reduce/reduce conflict between rule 48 and rule 46 on GE 
error: state 128: reduce/reduce conflict between rule 48 and rule 46 on GT 
error: state 128: reduce/reduce conflict between rule 48 and rule 46 on LE 
error: state 128: reduce/reduce conflict between rule 48 and rule 46 on LT 
error: state 128: reduce/reduce conflict between rule 48 and rule 46 on NEQ 
error: state 128: reduce/reduce conflict between rule 48 and rule 46 on EQ 
error: state 128: reduce/reduce conflict between rule 48 and rule 46 on DIVIDE 
error: state 128: reduce/reduce conflict between rule 48 and rule 46 on TIMES 
error: state 128: reduce/reduce conflict between rule 48 and rule 46 on MINUS 
error: state 128: reduce/reduce conflict between rule 48 and rule 46 on PLUS 
error: state 128: reduce/reduce conflict between rule 48 and rule 46 on RPAREN 

state 128: 

    boolean : exp . AND exp 
    boolean : exp . OR exp 
    arithmetic : MINUS exp . (reduce by rule 46) 
    arithmetic : exp . PLUS exp 
    arithmetic : exp . MINUS exp 
    arithmetic : exp MINUS exp . (reduce by rule 48) 
    arithmetic : exp . DIVIDE exp 
    arithmetic : exp . TIMES exp 
    comparison : exp . EQ exp 
    comparison : exp . NEQ exp 
    comparison : exp . GT exp 
    comparison : exp . LT exp 
    comparison : exp . LE exp 
    comparison : exp . GE exp 

다음은 yacc에 오류입니다. 물론 두 규칙 중 하나를 제거하면 충돌이 사라지지만 문법은 MINUS 기호를 잘못 구문 분석합니다.

이 오류를 진단 할 수 없습니다 - 어떤 아이디어입니까?

답변

3

야생 추측 : 규칙 중 하나에서 exp이 비어있을 수 있습니까? 그렇다면 exp은 선택 사항입니다 (예 : - exp 전과 같이 모호함이 생길 수 있습니다).

2

허용 된 답변 (그/그녀가 맞았습니다)으로서 - expepsilon으로 갈 수있는 시퀀스 제작에 실수가있었습니다.

sequence : LPAREN exp_sequence RPAREN() 
exp_sequence : (*epsilon*)() 
      | exp seq () 

seq : (*epsilon*)    () (*an exp sequence can be empty*) 
    | SEMICOLON exp seq() (*exps separated by semicolon*) 
:

여기
sequence : LPAREN exp_sequence RPAREN() 
exp_sequence : (*epsilon*)() 
     | exp seq () 

seq : (*epsilon*)    () (*an exp sequence can be empty*) 
    | SEMICOLON exp exp_sequence() (*exps separated by semicolon*) 

가 정정 코드이다 : 여기

코드의 잘못된 비트 (마지막 행 참조) 인