해피 / yacc가 시프트 될 때 감소합니다
-
15-11-2019 - |
문제
파서에서 일하고 있습니다. 나는 정말로 좌절했습니다. 언어로, 우리는 다음과 같은 표현을 가질 수 있습니다 :
new int[3][][]
.
또는
new int[3]
.
대부분의 빈 배열을 제외하고는 올바르게 파싱됩니다. 내 파서에서 나는 다음과 같습니다 :
Expression : int
char
null
(...many others...)
new NewExpression
.
및 newExpression은 다음과 같습니다.
NewExpression : NonArrayType '[' Expression ']' EmptyArrays
| NonArrayType '[' Expression ']'
.
그리고 emptyarays는 하나 이상의 빈 중괄호입니다 - 빈 문자열이 빈 문자열을 파생하면 20 개의 시프트 / 축소 충돌을 추가합니다.
EmptyArrays : EmptyArrays EmptyArray
| EmptyArray
EmptyArray : '[' ']'
.
그러나 Parser의 .info
파일을 볼 때 다음을 참조하십시오.
State 214¬
¬
▸ NewExpression -> NonArrayType lbrace Expression rbrace . EmptyArrays (rule 80)¬
▸ NewExpression -> NonArrayType lbrace Expression rbrace . (rule 81)¬
¬
▸ dot reduce using rule 81¬
▸ ';' reduce using rule 81¬
▸ ',' reduce using rule 81¬
▸ '+' reduce using rule 81¬
▸ '-' reduce using rule 81¬
▸ '*' reduce using rule 81¬
▸ '/' reduce using rule 81¬
▸ '<' reduce using rule 81¬
▸ '>' reduce using rule 81¬
▸ '<=' reduce using rule 81¬
▸ '>=' reduce using rule 81¬
▸ '==' reduce using rule 81¬
▸ '!=' reduce using rule 81¬
▸ ')' reduce using rule 81¬
▸ '[' reduce using rule 81 --I expect this should shift
▸ ']' reduce using rule 81¬
▸ '?' reduce using rule 81¬
▸ ':' reduce using rule 81¬
▸ '&&' reduce using rule 81¬
▸ '||' reduce using rule 81
.
우리가 상태 214에 있고 왼쪽 중괄호를 볼 수 있지만 스택으로 이동하여 빈 흔들림을 계속해서
NewExpression
로 구문 분석을 시작하여 수하물 밖으로 모든 초과를 벗기면, 추가 브래킷이 올바르게 구문 분석되어 올바르게 일어나는 일이 정확히 일어나고 있는지 확신하지 못합니다. 표현식이나 문이나 문법의 비 터미널이 왼쪽 중괄호로 시작할 수는 없습니다. 특히 Shift / Elduct Complict를 생성하는 IF / else 문에 대해 유사한 규칙이 있지만 다음 토큰이 다른 경우 이동을 선택합니다 (이 문제는 잘 설명되어 있음).
무엇이 잘못되었는지 알아낼 수 있도록 도와 줄 수 있습니까? 나는 당신의 도움에 정말로 감사 드리며, 나는 문제를 알아 내려고 노력하는 풍차에서 정말로 기울이고 있습니다.
해결책
You probably have a precedence set for '[' and/or ']' with something like %left '['
which causes this behavior. Remove that precedence declaration, and this will reveal the shift/reduce conflict you have here. As for why its a shift/reduce conflict, you probably also have a rule:
Expression: Expression '[' Expression ']'
for an array access. The problem being that since a NewExpression
is an Expression
it may be followed by an index like this, and when looking at the lookahead of '[', it can't tell whether that's the beginning of an index expression or the beginning of an EmptyArray
-- that would require 2-token lookahead.
One thing you could try for this specific case would be to have your lexer do the extra lookahead needed here and recognize []
as a single token.