パーサーLL -Wikipedia、無料百科事典
無料の百科事典であるウィキペディアから
パーサーLL これは、テキストを左から右に読んで、左を生成するパーサーであり、降順の方法を残します。人気のあるタイプのLLパーサーは、プラークで再発可能なパーサーです。
クラスパーサー ll(k) サインはサインによって運ばれ、「予想されるシンボル」を含む山を維持します。最初に開始記号とファイルエンドサインがあります。スタックの上部に、入り口の現在のシンボルと同じ端末記号がある場合、スタックの上部から取り外され、エントランスストリームを次のサインに移動します。別の端子記号がエラーを返した場合。そこに非緊急記号がある場合、それは削除され、このシンボルとから依存します k その後の入り口の標識は、適切なシンボルのセットを賭けます。
LL(1)は非常に貧弱なクラスです(しかし、多くの場合十分です)。たとえば、次のような単純な文法です。
- 式→number ‘+’式
- 式→数
表現を期待して数字を見るため、それはもう彼女のものではないので、それを杭に変えるかどうかはわかりません。
幸いなことに、この文法は同等のLL文法(1)に処方される可能性があります。
- 式→オプション番号
- オプションの融合→ε
- オプションの会社→ ‘+’式
文法のために解析委員会を構築しましょう:
- 式→iloczyn ‘+’式
- 表現→製品
- 製品→番号 ‘*’製品
- 製品→番号
まず、同等のLL文法に書き換える必要があります( k ) (この場合 k 1):
- 式→製品オプション
- オプションの融合→ε
- オプションの会社→ ‘+’式
- 製品→オプションの数
- オプションのライオネル→ε
- オプションの責任→ ‘*’製品
解析テーブル:
番号 | + | * | 終わり | |
表現 | Ilozynオプションの衝動 | 間違い | 間違い | 間違い |
オプション | 間違い | +式 | 間違い | e |
製品 | オプションの数 | 間違い | 間違い | 間違い |
オプション | 間違い | e | * 製品 | e |
式5 + 3 * 8 * 2 + 7 * 2の解析の後には次のとおりです。
スタック | エントリ |
---|---|
表現の終わり | 番号 +番号 *番号 *番号 +番号 *番号終了 |
オプションの製品 | 番号 +番号 *番号 *番号 +番号 *番号終了 |
オプション番号 | 番号 +番号 *番号 *番号 +番号 *番号終了 |
オプションの責任オプション | + number * number * number + number * end |
オプションの終わり | + number * number * number + number * end |
+式の終わり | + number * number * number + number * end |
表現の終わり | 番号 *番号 *番号 +番号 *番号終了 |
オプションの製品 | 番号 *番号 *番号 +番号 *番号終了 |
オプション番号 | 番号 *番号 *番号 +番号 *番号終了 |
オプションの責任オプション | *番号 *番号 +番号 *番号の終了 |
*オプションの製品 | *番号 *番号 +番号 *番号の終了 |
オプションの製品 | 番号 *番号 +番号 *番号の終了 |
オプション番号 | 番号 *番号 +番号 *番号の終了 |
オプションの責任オプション | *番号 +番号 *番号の終了 |
*オプションの製品 | *番号 +番号 *番号の終了 |
オプションの製品 | 番号 +番号 *番号の終了 |
オプション番号 | 番号 +番号 *番号の終了 |
オプションの責任オプション | + number * number end |
オプションの終わり | + number * number end |
+式の終わり | + number * number end |
表現の終わり | 番号 *番号終了 |
製品オプションの自由 | 番号 *番号の終わり |
オプションの責任の数 | 番号 *番号終了 |
オプションの自由 | *番号の終了 |
*オプションの製品 | *番号の終了 |
製品オプションの自由 | 番号の終わり |
オプションの責任の数 | 番号の終わり |
オプションの自由 | 終わり |
オプションのリバティエンド | 終わり |
終わり | 終わり |
非緊急記号ごとに文法をLL(1)にするためには、1つの末端シンボルの疑いがある後に生産を認識し、選択する必要があります。これは、1つの非緊急シンボルの生産の各ペアについて
- と 私 同じ端子記号を導出することはできません
- 同時に、空の文字列を取り出すことはできません 私
- zの場合 空の文字列を導き出すことは可能です フォロー(a)端末から始まる文字列を取ることはできません。同じように、zの場合 空の文字列を導出することが可能です。
これらの条件は同等です
- 私 それらは断絶コレクションでなければなりません
- もしも それから 私 それらは切断され、同様にいつ必要です それから 私 それらは断絶コレクションでなければなりません
文法をLL(1)に変換するためには、それは明確でなければなりませんが、すべての明確なことを変換できるわけではありません。
LL(1)文法を取得するチャンスを与える2つの変換があります。
- 左の再帰の排除
- 左側の因数分解
左の再帰の排除 [ 編集 | コードを編集します ]
我々は持っています
- 式→式 ‘+’番号
- 式→数
左の再帰は右に書き直すことができます:
- …
- …
書き換えます
左側の因数分解 [ 編集 | コードを編集します ]
我々は持っています
- expr 番号 ‘+’ expr
- expr 番号
最初のシンボル(端子と信頼性の低い)の数が同一であることを見ていきます。ここには、1つのシンボルだけがあります。右側は新しいシンボルに置き換えられます:それをplsexprと呼びましょう
- expr 番号plusexpr
- plusexpr ‘+’ expr
- plusexpr
2つ以上のプロダクションが同じで始まるとき:
- expr 番号 ‘+’ expr
- expr 番号 ‘ – ‘ expr
- expr 番号
に変わります
- expr 番号PlusMinusexpr
- foresminusexpr ‘+’ expr
- foresminusexpr ‘ – ‘ expr
- foresminusexpr
場合によっては、文法のあいまいな定義が必要である場合のように、if..then..else:
- 統計 exprの場合、統計統計統計
- 統計 exprの場合、stat
左側 – ハンドファクター化:
- 統計 exprの場合、stat elsestat
- elsstat それ以外の状態
- elsstat
文法は、他のシンボルが遭遇するとき、エルスティのために曖昧です。貪欲な選択をすることでこれを解決します
- elsstat それ以外の状態
それ以外の場合は、選択した場合
それ以前の場合は、他の人の一部になる可能性があります。
LLパーサーは、相互に引き起こす機能のセットを使用して手動で簡単に記述することもできます。
サイン next_nak ; / *グローバル変数 */ 空所 Parsujwyna () { もしも ( next_nak == 番号 )) { Parsujiloczyn (); パルスヨッピング肉 (); } else {
błąd();
}
}
void parsujIloczyn() {
if (następny_znak == liczba)
{
następny_znak = odczytaj_znak();
parsujOpcjonalneRazyIloczyn();
} else {
błąd();
}
}
void parsujOpcjonalnePlusWyrażenie() {
if (następny_znak == '+')
{
następny_znak = odczytaj_znak();
parsujWyrażenie();
} else if (następny_znak == KONIEC_PLIKU) {
/* pusty ciąg znaków */
} else {
błąd();
}
}
void parsujOpcjonalneRazyIloczyn() {
if (następny_znak == '*')
{
następny_znak = odczytaj_znak();
parsujIloczyn();
} else if (następny_znak == '+' || następny_znak == KONIEC_PLIKU){
/* pusty ciąg znaków */
} else {
błąd();
}
}
void parsuj()
{
następny_znak = odczytaj_znak();
parsujWyrażenie();
if (następny_znak != KONIEC_PLIKU)
błąd();
}
- Alfred V. Aho、Ravi Sethi、Jeffrey D. Ullman: コンパイラ。ルール、方法、ツール 。ワルシャワ:Wnt、2002。ISBN 83-204-2656-1 。
Recent Comments