シフトする必要がある場合は、幸せ/ 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 ']'
.
とその後、EmptyArraysは1つ以上の空きブレースです - EmptyArraysが空の文字列を派生させた場合は、20のシフト/競合を減らす:
EmptyArrays : EmptyArrays EmptyArray
| EmptyArray
EmptyArray : '[' ']'
.
しかしながら、パーサーの.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
で解析を開始することで、荷物から過剰なすべてを取り除くと、追加のブラケットは正しく解析されます。文法の表現やステートメントまたは任意の非端末が左ブレースから始めることはできません。特にif / elseステートメントの類似ルールがあるため、Shift / Reduceの競合を生成するが、次のトークンが他のものである場合に変更を選択した場合(この問題はよく文書化されています)。
あなたは私が何が間違っているのかを理解するのを手伝ってくれる?私は本当にあなたの助けに感謝しています、私は問題を把握しようとしている風車で本当に傾いています。
解決
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.