私は小さなパーサを書こうとしています。残念ながら、私は「シフトを減らす紛争」を起こします。文法は私の強みではありません。私はこれを小さなものにする必要があります。修正された文法を与える解決策は、エラーを生成する文法の縮小です:文法の中でIF-ELSEの競合を減らす/減らす
stmts_opt -> stmts
;
stmts -> stmt
| stmts stmt
| stmsts
;
stmt -> id
| ITERATE content_stmt
| IF test then content_stmt ELSE content_stmt
| IF test then content_stmt
;
content_stmt: BEGIN stmt_opt END
| stmt
;
修正された文法を与える解決法は高く評価されます。
編集:私は私の文法はRICIの答え@合ったが、問題が解決しない修正
。ここに私の実際の文法プロダクションです:
BEGINNING-OF-PROGRAM
BEGINNING-OF-EXECUTION
IF not-next-to-a-beeper THEN
move;
IF not-facing-north THEN
turnleft;
ELSE <--- ERROR
turnleft;
IF not-facing-east THEN
IF not-facing-west THEN
turnleft;
turnoff
END-OF-EXECUTION
END-OF-PROGRAM
私が最初ELSE
のエラーを取得しています:ここで
prog: BEGIN_PROG def_sprogram BEGIN_EXEC stmts_opt END_EXEC END_PROG
{() }
;
def_sprogram: /* empty */ {() }
| define_new def_sprogram {() }
;
define_new: DEFINE_NEW_INSTRUCTION ID AS content_stmt SEMI { }
;
stmts_opt: /* empty */ {() }
| stmts {() }
;
stmts: stmt {() }
| stmts SEMI stmt {() }
| stmts SEMI {() }
;
content_stmt: BEGIN stmts_opt END {() }
| stmt {() }
;
stmt: open_stmt {() }
| closed_stmt {() }
;
open_stmt: ITERATE INT TIMES open_stmt {() }
| WHILE test DO open_stmt {() }
| IF test THEN closed_stmt ELSE open_stmt {() }
| IF test THEN stmt {() }
;
closed_stmt: simple_stmt {() }
| ITERATE INT TIMES closed_stmt {() }
| WHILE test DO closed_stmt {() }
| IF test THEN closed_stmt ELSE closed_stmt {() }
;
は、私がテストしてい例です。 @riciが示唆しているように簡単な優先順位を宣言しようとしました:
%nonassoc THEN
%nonassoc ELSE
しかし、それでもエラーは解決されませんでした。
yacc/bisonが正しい解決法を選択しているため、shift-reduceの矛盾が曖昧な曖昧さから生じる場合は、文法は正しく動作します。警告を取り除きたい場合は、ここで「他の人を抱きしめる」を検索してください。 – rici
私はcamlyaccを使用しており、警告ではなくエラーが発生しています。私はここで検索しようとしましたが、私の文法は少し異なります(BEGINとENDで)、提案された解決策は私のためには機能しませんでした。 –
これをエラーにするのは面倒です。それはしないでください。しかし、開始トークンと終了トークンは何の影響も与えてはなりません。あなたは何をしなかったのですか? – rici