2

LR ファミリーの構文解析ジェネレーター (YACC、BISON など) の文法規則を考えてみましょう。

Nonterminal : [ lookahead not in {Terminal1, ..., TerminalN} ] Rule ;

制限があることを除いて、これは通常のルールです。このルールで作成されたフレーズは、で始まることはできませんTerminal1, ..., TerminalN。(確かに、この規則は一連の通常の規則に置き換えることができますが、より大きな文法になります)。これは、競合を解決するのに役立ちます。

問題は、そのような制限を受け入れる LR テーブル構築アルゴリズムの修正があるかどうかです。そのような変更が可能であるように私には思えます(優先関係のように)。

確かに、実行時にチェックできますが、コンパイル時のチェックを意味します ( yacc 互換ジェネレーターの%prec%left%rightおよびディレクティブなどの解析テーブルの作成中に実行されるチェック)。%nonassoc

4

1 に答える 1

1

これが不可能な理由はわかりませんが、それが役立つ明確な理由もわかりません。心に留めている例はありますか?

これを行う最も簡単な方法は、括弧内に記載されている文法変換を行うことです。これにより、より大きな文法が作成されますが、LR 状態の数が人為的に増加することはありません。

少し手を振るだけの基本的な変換:

端末制限のあるプロダクションの場合:

  • プロダクションが null 非許容の非ターミナルで開始する場合は、非ターミナルをターミナル制限バージョンに置き換えます。

  • 生産が端末制限リストの端末で開始された場合、生産を削除します

  • 端末制限リストにない端末で生産を開始する場合は、変更の必要はありません。

プロダクションが null 許容の非終端記号で開始する場合、null 許容の非終端記号の 2 つのバージョンを作成する必要があります。次に、プロダクションの 2 つのバージョンを作成します。1 つは新しい非ターミナルのそれぞれから始まります。次に、上記の変換を適用しますが、「で始まる」を解釈すると、「常に null の非終端記号の後から始まる」という意味になります。

上記の変換は、少なくとも LR(0) および LALR(1) の構築では、基礎となる SLR マシンの構築中にオンザフライで実行できるため、実際に文法を変更する必要はありません。

于 2013-04-21T06:02:41.783 に答える