文法: http://pastebin.com/ef2jt8Rg y.output: http://pastebin.com/AEKXrrRG
それらの競合がどこにあるのかわかりません。誰かがこれを手伝ってくれますか?
文法: http://pastebin.com/ef2jt8Rg y.output: http://pastebin.com/AEKXrrRG
それらの競合がどこにあるのかわかりません。誰かがこれを手伝ってくれますか?
y.output ファイルは、競合がどこにあるかを正確に示します。最初のものは状態 4 にあるため、下に移動して状態 4 を見ると、次のように表示されます。
state 4
99 compound_statement: '{' . '}'
100 | '{' . statement_list '}'
IDENTIFIER shift, and go to state 6
:
IDENTIFIER [reduce using rule 1 (threat_as_ref)]
IDENTIFIER [reduce using rule 2 (func_call_start)]
これは、この状態 ( a を解析し、 acompound_statement
を見た{
) で、次のトークンがIDENTIFIER
であるのを見て、できることが 3 つあることを示しています。つまり、トークンのシフト ( a の始まりstatement_list
)、threat_as_ref
空生産、または空生産を削減しfunc_call_start
ます。
角かっこは、それらのアクションを実行しないことを決定したことを示しています。デフォルトの「reduce よりも shift を優先する」競合解決は、常に shift を実行することを意味します。
あなたの文法の問題は、これらの空のルールです.IDENTIFIERをシフトする前にそれらを減らす必要がありますが、それらが有効かどうかを知るために、パーサーは識別子の後にトークンを見る必要があります threat_as_ref
. これが関数呼び出しの開始である場合にのみ削減する必要があります ( IDENTIFIER の後に a があることに依存します)。あなたの特定のケースでは、文法は LALR(2) (2 トークンの先読みで十分です) ですが、LALR(1) ではないため、バイソンはそれを処理できません。func_call_start
func_call_start
(
これらの空のルールを取り除くだけで修正できます --func_call_start
アクションはまったくなく、 のアクションを のアクションthreat_as_ref
に移動できますがvariable
、将来これらのルールが必要な場合は問題になる可能性があります。
(1) 奇妙に見えるものが少なくとも 1 つあります。の作品は の作品expression_statement
と似てpostfix_statement
いますが、まったく同じではありません。'(' および ')' トークンはありません。
expression_statement
: ';'
| expression ';'
| func_call_start IDENTIFIER { ras_parse_variable_psh($2); aFree($2); } func_call_end ';'
| func_call_start IDENTIFIER { ras_parse_variable_psh($2); aFree($2); } argument_expression_list func_call_end ';'
;
はexpression
でありprimary_expression
、 はIDENTIFIER
であり、func_call_start
およびfunc_call_end
はイプシロン (null) 生成であるため、入力が与えられた場合
foo;
パーサーは、適用するかどうかを決定する必要があります
expression_statement : expression ';'
また
expression_statement : func_call_start IDENTIFIER { ras_parse_variable_psh($2); aFree($2); } func_call_end ';'
(2) また、これについては確信が持てませんが、イプシロンの非終端記号threat_as_ref
が問題を引き起こしているのではないかと思います。私はそれを追跡していませんが、パーサーが avariable_ref
か aかを判断しなければならない場合があるかもしれませんvariable
。