0

私はパーサーに取り組んでいて、本当にイライラしています。この言語では、次のような表現を使用できます。

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のshift/reduce競合が追加されます。

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で左中括弧が表示されている場合は、それをスタックにシフトして、EmptyArrayの解析を続行する必要があります。

NewExpression解析を開始して手荷物から余分なものをすべて取り除くと(たとえば) 、追加の角かっこが正しく解析されるため、何が起こっているのか正確にはわかりません。式、ステートメント、または文法の非終端記号を左中括弧で始めることはできません。特に、if / elseステートメントについて同様のルールがあり、shift / reduceの競合が発生しますが、次のトークンがelseの場合はシフトを選択するためです(この問題は十分に文書化されています)。

何が悪いのか理解するのを手伝ってもらえますか?私は本当にあなたの助けに感謝します、私は問題を理解しようとしている風車に本当に傾いています。

4

1 に答える 1

1

おそらく、「[」および/または「]」の優先順位が設定されており、%left '['このような動作が発生します。その優先順位宣言を削除すると、ここにあるシフト/削減の競合が明らかになります。シフト/リデュースの競合が発生する理由については、おそらく次のルールもあります。

Expression: Expression '[' Expression ']'

配列アクセス用。問題は、aNewExpressionが anExpressionであるため、このようなインデックスが続く可能性があり、'[' の先読みを見ると、それがインデックス式の始まりなのか、それとも a の始まりなのかを判断できないことEmptyArrayです。 2 トークンの先読みが必要になります。

この特定のケースで試すことができることの 1 つは、ここで必要な追加の先読みをレクサーに実行させ[]、単一のトークンとして認識させることです。

于 2011-02-21T03:40:47.683 に答える