シフト/排除簡素化yaacファイルです:2シフト/競合を減らすがありはここで同じ接頭辞で生成規則に起因する紛争を減らす
%token CONTEXT_ // the corresponding string is "context"
%token CONTEXTREF_ //"contextref"
%token IS_ //"is"
%token ID_L //"id_l"
%token ID_L1 //"id_l1"
%token LIB_
%start design_file
%%
design_file :design_unit
|design_file design_unit
;
design_unit :context_cl LIB_
|context_decl
;
context_cl : /* empty */ { }
|context_cl context_ref
;
context_decl :CONTEXT_ ID_L IS_ ';'
;
context_ref :CONTEXT_ ID_L1 '.' ID_L ';'
;
。
CONTEXT_ shift, and go to state 1 CONTEXT_ [reduce using rule 5 (context_cl)]
ルール5はcontext_cl : /* empty */ { }
です。
一般に、これは問題ではありませんが、パーサはほとんどの場合よく機能します。 しかし、一つの奇妙な場合は、ソースファイルに対して次のように:
context id_l is ...
...
パーサがシフトしたが故に構文エラーの原因となる、context id_l is ...
を解析するcontext_ref :CONTEXT_ ID_L1 '.' ID_L ';'
を使用して、小さくなりません。
したがって、私は競合を排除する必要があります。 私はそれらが最初にを持つ規則context_decl
とcontext_ref
によって引き起こされると思います。
私の推測を検証するために、context_ref :CONTEXT_ ID_L1 '.' ID_L ';'
をcontext_ref :CONTEXTREF_ ID_L1 '.' ID_L ';'
に変更しました。次に、競合はなく、構文エラーもありません。
しかし、私はこのようにcontext_ref
を置き換えることはできません。これが標準です。
他の方法でこれらの2つの競合を回避するにはどうすればよいですか?あるいは、この種の紛争に対処するための一般的な方法はありますか?
シフト/リダクションの競合の場合、パーサーはシフトするのではなく減らすことを選択しますか?なぜなら、パーサーは常に減らすことになると思うからです。私はあなたの「断続的」構文エラーがどこから来ているか分からない
私は再現することはできませんあなたが説明する問題。私はあなたが指定した文法を正確に使って、あなたが引用したシフト/リダクションの競合を正確に得ました。すべてがチェックアウトするように私はレクサーがどのように見えるかを推測し、デバッグモードでは入力 'context id_l is; 'でそれを実行しました。それはエラーなしで入力を認識した。 shift/reduce競合の解決のため、 'context id_l1 ...'を解析しません。それはあなたが意味することですか?もしそうなら、あなたの質問を編集してください。私はそれに答えようとします。それ以外の場合は、[完全]と[検証可能]を重視して[mcve]を押してください。 – rici
構文エラーが断続的に発生しました。ですから、シフト/リダクションの競合を排除したいだけです。@ rici –