パーサーLL -Wikipedia、無料百科事典

before-content-x4

無料の百科事典であるウィキペディアから

after-content-x4

パーサーLL これは、テキストを左から右に読んで、左を生成するパーサーであり、降順の方法を残します。人気のあるタイプのLLパーサーは、プラークで再発可能なパーサーです。

クラスパーサー ll(k) サインはサインによって運ばれ、「予想されるシンボル」を含む山を維持します。最初に開始記号とファイルエンドサインがあります。スタックの上部に、入り口の現在のシンボルと同じ端末記号がある場合、スタックの上部から取り外され、エントランスストリームを次のサインに移動します。別の端子記号がエラーを返した場合。そこに非緊急記号がある場合、それは削除され、このシンボルとから依存します k その後の入り口の標識は、適切なシンボルのセットを賭けます。

LL(1)は非常に貧弱なクラスです(しかし、多くの場合十分です)。たとえば、次のような単純な文法です。

  • 式→number ‘+’式
  • 式→数

表現を期待して数字を見るため、それはもう彼女のものではないので、それを杭に変えるかどうかはわかりません。

幸いなことに、この文法は同等のLL文法(1)に処方される可能性があります。

after-content-x4
  • 式→オプション番号
  • オプションの融合→ε
  • オプションの会社→ ‘+’式

文法のために解析委員会を構築しましょう:

  • 式→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つの非緊急シンボルの生産の各ペアについて

a a | b {displaystyle arightarrow alpha | beta {:}}

  1. 同時に、空の文字列を取り出すことはできません
  2. zの場合

これらの条件は同等です

  1. もしも

文法をLL(1)に変換するためには、それは明確でなければなりませんが、すべての明確なことを変換できるわけではありません。
LL(1)文法を取得するチャンスを与える2つの変換があります。

  1. 左の再帰の排除
  2. 左側の因数分解

左の再帰の排除 [ 編集 | コードを編集します ]

我々は持っています

  • 式→式 ‘+’番号
  • 式→数

左の再帰は右に書き直すことができます:

書き換えます

左側の因数分解 [ 編集 | コードを編集します ]

我々は持っています

  • expr
  • expr

最初のシンボル(端子と信頼性の低い)の数が同一であることを見ていきます。ここには、1つのシンボルだけがあります。右側は新しいシンボルに置き換えられます:それをplsexprと呼びましょう

  • expr
  • plusexpr
  • plusexpr

2つ以上のプロダクションが同じで始まるとき:

  • expr
  • expr
  • expr

に変わります

  • expr
  • foresminusexpr
  • foresminusexpr
  • foresminusexpr

場合によっては、文法のあいまいな定義が必要である場合のように、if..then..else:

  • 統計
  • 統計

左側 – ハンドファクター化:

  • 統計
  • elsstat
  • elsstat

文法は、他のシンボルが遭遇するとき、エルスティのために曖昧です。貪欲な選択をすることでこれを解決します

  • elsstat

それ以外の場合は、選択した場合

ϵ {displaystyle epsilon}

それ以前の場合は、他の人の一部になる可能性があります。

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

after-content-x4