レクサー対パーサー


308

レクサーとパーサーは、理論的には本当に違いますか?

正規表現を嫌うのはおしゃれなようです。コーディングホラー別のブログ投稿

ただし、人気のある字句ベースのツールであるpygmentsgeshi、またはprettifyはすべて正規表現を使用します。彼らは何かを語っているようです...

字句解析が十分な場合、EBNFはいつ必要ですか?

これらのレクサーによって生成されたトークンをバイソンまたはアントラーパーサージェネレーターで使用した人はいますか?


2
はい。自動ホットキーを解析しようとしています。Pygmentsを使用して構文ハイライターを非常に高速に構築できました。しかし、antlrの方がはるかに時間がかかります... 2つのツール間の多くの相互受粉は見たことがありません。
Naveenは

67
それらが誤用されたときに正規表現を嫌うのはその唯一の流行です。多くの人は、コンテキストフリーの解析が必要なときに正規表現を使用しようとします。彼らは常に失敗します。そして、彼らは正規表現技術のせいです。それはあなたのハンマーがボロボロののこぎりであると不平を言うのによく似ています。確かに、あなたは多くの同情を得ることはありません。
Ira Baxter、

2
ありがたいことに、antlrで速度を上げ始めています。多くの字句解析はコンテキストフリーであり、時にはコンテキストにも依存します。
Naveen

1
レクサーとパーサーの問題の基本的な側面の1つは、レクサーが有限オートマトン(FSA)、またはより正確には有限トランスデューサ(FST)に基づいていることです。ほとんどの解析形式(コンテキストフリーだけではない)は、FSAまたはFSTのアプリケーションとの共通部分の下で閉じられます。したがって、レクサーに対してより単純な正規表現ベースの形式を使用しても、より複雑なパーサー形式の構文構造の複雑さが増すことはありません。これは、言語の構造とセマンティクスを定義する際の絶対的な主要なモジュール性の問題であり、投票数の多い回答では喜んで無視されています。
babou 14

それはレクサーとパーサはしていないことに留意すべきである持って異なるように、例えばLLLPGとANTLRの以前のバージョンは、レクサーとパーサの両方に同じLL(k)を解析するシステムを使用しています。主な違いは、正規表現は通常、レクサーには十分ですが、パーサーには不十分であることです。
Qwertie 2016

回答:


475

パーサーとレクサーに共通するもの:

  1. 彼らは入力からいくつかのアルファベットの記号を読みます。

    • ヒント:アルファベットは必ずしも文字である必要はありません。しかし、それはパーサー/レクサーが理解する言語にとって不可分なシンボルでなければなりません。
    • レクサーの記号:ASCII文字。
    • パーサーのシンボル:文法の終端記号である特定のトークン。
  2. 彼らはこれらの記号を分析し、彼らが理解した言語の文法とそれらを一致させようとします。

    • 通常、本当の違いはここにあります。詳細については、以下を参照してください。
    • レクサーが理解できる文法:通常の文法(Chomskyのレベル3)。
    • パーサーが理解できる文法:文脈自由文法(Chomskyのレベル2)。
  3. 彼らは彼らが見つけた言語の部分に意味論を意味します。

    • レクサーは、語彙素(入力からのシンボルの文字列)を特定のトークンとして分類することで意味を付けます。例えばこれらのすべての語彙素は:*==<=^C / C ++レクサーによってトークン「演算子」として分類されます。
    • パーサーは、入力からのトークンの文字列(文)を特定の非終端記号として分類し、解析ツリーを構築することにより、意味を付加します。例えば、これらすべてのトークンの文字列は:[number][operator][number][id][operator][id][id][operator][number][operator][number]C / C ++パーサによって非終端「表現」として分類されます。
  4. 認識された要素にいくつかの追加の意味(データ)を付けることができます。

    • レクサーは、適切な数値を構成する文字シーケンスを認識すると、それをそのバイナリ値に変換し、「数値」トークンとともに格納できます。
    • 同様に、パーサーが式を認識すると、パーサーはその値を計算し、構文ツリーの「式」ノードに格納できます。
  5. それらはすべて、彼らが認識する言語の適切なを出力に生成します。

    • レクサーはトークンを生成します。トークンは、認識できる通常の言語のです。各トークンは内部構文を持つことができます(レベル2ではなくレベル3です)が、それは出力データとそれらを読み取るものには関係ありません。
    • パーサーは構文ツリーを生成します。構文ツリーは構文木が認識する文脈自由言語の表現です。通常、ドキュメント/ソースファイル全体が適切なであるため、ドキュメント/ソースファイル全体の大きなツリーは1つだけです。しかし、パーサーが一連の構文ツリーを出力に生成できなかった理由はありません。たとえば、プレーンテキストに貼り付けられたSGMLタグを認識するパーサーである可能性があります。だから、よトークン化一連のトークンにSGML文書を:。[TXT][TAG][TAG][TXT][TAG][TXT]...

ご覧のとおり、パーサーとトークナイザーには多くの共通点があります。1つのパーサーを他のパーサーのトークナイザーにすることができます。これは、ある言語からの文が他のより高いレベルのアルファベット記号になることができるのと同じ方法で、入力トークンを独自のアルファベットからの記号(トークンは単にアルファベットの記号です)として読み取ります。言語。たとえば、*-M(「モールス符号記号」として)アルファベットの記号である場合、これらのドットとラインの文字列をモールス符号でエンコードされた文字として認識するパーサーを構築できます。言語「モールス符号」の文章は、可能性があり、トークン他のいくつかのパーサーの、のためにこれらのトークンその言語の原子記号です(例:「英単語」言語)。そして、これらの「英単語」は、「英語の文」言語を理解する一部の高レベルのパーサーのトークン(アルファベットの記号)になる可能性があります。そして、これらすべての言語は文法の複雑さだけが異なります。これ以上何もない。

では、これらの「チョムスキーの文法レベル」についてはどうでしょうか。そうですね、Noam Chomskyは文法をその複雑さに応じて4つのレベルに分類しました。

  • レベル3:通常の文法

    彼らは、あること、彼らは唯一のアルファベットの記号で構成することができ、正規表現を使用(ab)、彼らの連結は(abababbb。ETD)、または代替(例えばa|b)。
    それらは、NFA(非決定論的有限オートマトン)またはより優れたDFA(決定論的有限オートマトン)のような有限状態オートマトン(FSA)として実装できます。
    通常の文法は、ネストされた構文では処理できません。たとえば、適切にネストされた/マッチした括弧(()()(()()))、ネストされたHTML / BBcodeタグ、ネストされたブロックなど。
  • レベル2:文脈自由文法

    構文ツリーにネストされた再帰的な自己相似ブランチを含めることができるため、ネストされた構造を適切に処理できます。
    それらは、スタック付きの状態オートマトンとして実装できます。このスタックは、構文のネストレベルを表すために使用されます。実際には、それらは通常、マシンのプロシージャコールスタックを使用してネストレベルを追跡し、構文内のすべての非終端記号に対して再帰的に呼び出されるプロシージャ/関数を使用するトップダウンの再帰下降パーサーとして実装されます。
    ただし、状況依存の構文では処理できません。たとえば、式がx+3あり、あるコンテキストではこれxが変数の名前になり、別のコンテキストでは関数の名前になる場合があります。
  • レベル1:文脈依存文法

  • レベル0:無制限の文法
    再帰的に列挙可能な文法とも呼ばれます。


70
そうそう?それで、それらの「単語またはトークン」は何ですか?それらは通常の言語の単なるであり、アルファベットの文字で構成されています。そして、パーサーのそれらの「構造」または「木」は何ですか?それらも文章ですが、特定のトークンがアルファベット記号である別の高水準言語です。違いはあなたが言ったことではなく、使用されている言語の複雑さです。解析理論についてのハンドブックで-1に直面してください。
SasQ

3
@SasQレクサーとパーサーの両方がいくつかの文法と一連のトークンを入力として受け取ると言うのは公平でしょうか?
Parag

4
かなりそうです。どちらも、認識したアルファベットから一連の記号を取り出します。レクサーの場合、このアルファベットはプレーン文字のみで構成されています。パーサーの場合、アルファベットは、定義されているすべての終端記号で構成されます。レクサーを使用せず、1文字の識別子や1桁の数字などを使用する場合、それらも文字になる可能性があります(開発の最初の段階では非常に役立ちます)。ただし、トークンは優れた抽象概念であるため、通常はトークン(字句クラス)です。トークンが表す実際の語彙素(文字列)は変更でき、パーサーは変更を認識しません。
SasQ 2012

6
たとえばSTMT_END、構文の最後の記号(パーサー用)を使用して、命令の終わりを示すことができます。これで、同じ名前のトークンが関連付けられ、レクサーによって生成されます。しかし、それが表す実際の語彙素を変更することができます。例えば。あなたが定義することができるSTMT_ENDよう;、ソースコードのように- C / C ++を持っています。またはend、Pascalスタイルに似たものになるように定義することもできます。または'\n'、Pythonのように、命令を行末で終了するように定義することもできます。ただし、命令(およびパーサー)の構文は変更されません:-)変更する必要があるのはレクサーのみです。
SasQ 2012

24
ウィキペディアとグーグルの時間は役に立たなかったが、チョムスキーの文法を3分で説明した。ありがとうございました。
エンレイ

107

はい、それらは理論上および実装において非常に異なります。

語彙素は、言語要素を構成する「単語」を認識するために使用されます。これは、そのような単語の構造は一般に単純であるためです。正規表現はこの単純な構造の処理に非常に優れており、レクサーの実装に使用される非常に高性能な正規表現マッチングエンジンがあります。

パーサーは、言語句の「構造」を認識するために使用されます。そのような構造は一般に「正規表現」が認識できるものをはるかに超えているため、そのような構造を抽出するには「コンテキスト依存」パーサーが必要です。状況依存パーサーは構築が難しいため、技術上の妥協点は「コンテキストフリー」文法を使用し、パーサー(「シンボルテーブル」など)にハックを追加して状況依存部分を処理することです。

字句解析技術も構文解析技術もすぐになくなるとは思われません。

いわゆるスキャナーレスGLRパーサーで現在検討されているように、「解析」テクノロジーを使用して「単語」を認識することを決定することで、それら統合できます。より一般的な機械を必要としない問題に適用することが多いため、これには実行時のコストがかかります。通常、その費用はオーバーヘッドで負担します。多くの空きサイクルがある場合、そのオーバーヘッドは問題にならない場合があります。大量のテキストを処理する場合は、オーバーヘッドが問題となり、従来の正規表現パーサーが引き続き使用されます。


40
いい説明だ、イラ。類推に追加:レクサーは単語を正しくすることについてですが、パーサーは文章を正しくすることです。「see spot run」と「spot run See」は、レクサーに関する限り、どちらも有効です。フレーズ構造が間違っていると判断するには、パーサーが必要です(英語の文法)。
アラン

ツリーウォーカーはパーサーと同じように、パーサーはレクサーと同じです。理論がこれほど異なるとは確信していません。antlr.org / wiki / display / 〜admin / ANTLR + v4 + lexersですが、それらの間の規約の違いを理解し始めています...
Naveen

4
理論は非常に異なります。ほとんどのパーサーテクノロジーは、文脈自由言語をある程度処理しようとしています(一部はLALRなど一部のみを実行し、一部はすべてGLRなど)。ほとんどのレクサー技術は、正規表現のみを実行しようとします。
Ira Baxter

3
それは多くの異なる人々によって提案され、異なる用語やアルゴリズムを使用しているため、理論は異なります。しかし、それらをよく見ると、類似点を見つけることができます。たとえば、左再帰の問題はNFAの非決定性の問題と非常に似ており、左再帰の削除は非決定性の削除とNFAからDFAへの変換と似ています。トークンはトークナイザー(出力)の文ですが、パーサー(入力)のアルファベット記号です。私は違い(チョムスキーレベル)を否定しませんが、類似点はデザインに大きく役立ちます。
SasQ

1
私の部下はカテゴリー理論に興味を持っていました。シーブのカテゴリー理論の概念がすべての種類のパターンマッチングをカバーする方法を示し、抽象的なカテゴリー仕様からLR解析を導出することができました。したがって、実際には、十分に抽象化すれば、そのような共通点を見つけることができます。カテゴリ理論の要点は、「ずっと上」に抽象化できることが多いことです。違いをなくすカテゴリー理論パ​​ーサーを構築できると思います。しかし、それを実際に使用する場合は、特定の問題ドメインにインスタンス化する必要があり、その違いが現実のものとして現れます。
Ira Baxter

32

字句解析が十分な場合、EBNFはいつ必要ですか?

EBNFは実際には文法の能力に多くを追加しません。これは、標準のチョムスキーの正規形(CNF)文法規則に対する、便利/ショートカット表記/ 「構文糖」にすぎません。たとえば、EBNFの代替:

S --> A | B

CNFでは、代替の各プロダクションを個別にリストするだけで達成できます。

S --> A      // `S` can be `A`,
S --> B      // or it can be `B`.

EBNFのオプション要素:

S --> X?

null可能なプロダクション、つまり空の文字列で置き換えることができるプロダクション(ここでは空のプロダクションのみで表されます。他のものはイプシロンまたはラムダまたは交差した円を使用します)を使用してCNFで達成できます。

S --> B       // `S` can be `B`,
B --> X       // and `B` can be just `X`,
B -->         // or it can be empty.

B上記の最後のような形式のプロダクションは、他のプロダクションにあるものをすべて消去できるため(他のものではなく空の文字列を生成する)、「消去」と呼ばれます。

EBNFのゼロ回以上の繰り返し:

S --> A*

再帰的なプロダクション(つまり、どこかに自分自身を埋め込むプロダクション)を使用してobtanを実行できます。それは2つの方法で行うことができます。最初のものは左再帰です(トップダウン再帰下降パーサーはそれを解析できないため、通常は回避する必要があります)。

S --> S A    // `S` is just itself ended with `A` (which can be done many times),
S -->        // or it can begin with empty-string, which stops the recursion.

(最終的に)空の文字列が生成され、その後に0個以上Aのsが続くことがわかっているため、同じ文字列(同じ言語ではない!)はright-recursionを使用して表現できます。

S --> A S    // `S` can be `A` followed by itself (which can be done many times),
S -->        // or it can be just empty-string end, which stops the recursion.

そして、+EBNFからの1回以上の繰り返しになると、

S --> A+

これを1つに分解し、以前A*同じように使用することで実行できます。

S --> A A*

これは、CNFでそのように表現できます(ここでは正しい再帰を使用しています。もう1つは練習として自分で考えてみてください)。

S --> A S   // `S` can be one `A` followed by `S` (which stands for more `A`s),
S --> A     // or it could be just one single `A`.

これを知っていれば、正規表現の文法(つまり、正規文法)は、終端記号のみから構成される単一のEBNFプロダクションで表現できるものとして認識できるはずです。より一般的には、次のようなプロダクションを見ると、通常の文法を認識できます。

A -->        // Empty (nullable) production (AKA erasure).
B --> x      // Single terminal symbol.
C --> y D    // Simple state change from `C` to `D` when seeing input `y`.
E --> F z    // Simple state change from `E` to `F` when seeing input `z`.
G --> G u    // Left recursion.
H --> v H    // Right recursion.

つまり、空の文字列、終端記号、置換と状態変更のための単純な非終端記号のみを使用し、再帰を使用して繰り返しを実現します(反復は単なる線形再帰であり、ツリーのように分岐しません)。これらよりも高度なものは何もないので、通常の構文であり、レクサーだけでそれを実行できます。

ただし、構文で自明でない方法で再帰を使用すると、次のようなツリーのような自己相似のネストされた構造が生成されます。

S --> a S b    // `S` can be itself "parenthesized" by `a` and `b` on both sides.
S -->          // or it could be (ultimately) empty, which ends recursion.

そうすれば、これを正規表現では実行できないことを簡単に確認できます。これは、それを単一のEBNFプロダクションに解決することができないためです。最終的にはS無期限に代用されることになり、常に両側にaとが追加さbれます。レクサーは(具体的に:有限状態オートマトンは、レクサーで使用される)は、それらがどのように多くを知らないので、任意の数(?彼らは有限で、覚えておいてください)に数えることができないaので、多くので均等にそれらを一致させるためにあったのb秒。このような文法は(少なくとも)文脈自由文法と呼ばれ、パーサーが必要です。

文脈自由文法は解析がよく知られているため、プログラミング言語の構文を記述するために広く使用されています。しかし、それだけではありません。同時に、より一般的な文法が必要な場合があります-同時に、独立して数えることがもっと多い場合。たとえば、丸かっこと角かっこを交互に使用できる言語を記述したいが、相互に正しくペアにする必要がある場合(中かっこで中かっこ、丸いかで丸める)。この種の文法は文脈依存と呼ばれます。左(矢印の前)に複数の記号があることでそれを認識できます。例えば:

A R B --> A S B

左側にあるこれらの追加のシンボルは、ルールを適用するための「コンテキスト」と考えることができます。いくつかの前提条件があるかもしれません、など事後条件は、例えば、上記のルールが置き換えられますRS、それが間にいたときだけABそれらを残し、AそしてB変わらずに自分自身を。この種の構文は本格的なチューリングマシンが必要なため、解析が非常に困難です。まったく別の話なので、ここで終わります。


1
あなたは、EBNFが「標準のチョムスキーの正規形(CNF)文法規則に対する単なる便宜/ショートカット表記/「構文糖」」であると述べています。しかし、CNFは現在のトピックとはほとんど関係ありません。EBNFは簡単に標準のBNFに変換できます。限目。標準のBNFの構文糖です。
バブー2014年

11

質問されたとおりに質問に答えるため(他の答えに現れるものを過度に繰り返さずに)

受け入れられた回答で示唆されているように、レクサーとパーサーはそれほど違いはありません。どちらも単純な言語形式に基づいています。レクサー用の通常の言語と、ほとんどの場合、パーサー用のコンテキストフリー(CF)言語です。どちらも、かなり単純な計算モデルである有限状態オートマトンとプッシュダウンスタックオートマトンに関連付けられています。通常の言語はコンテキストフリー言語の特殊なケースであるため、やや複雑なCFテクノロジーを使用してレクサーを作成できます。しかし、少なくとも2つの理由から、それは良い考えではありません

プログラミングの基本的なポイントは、システムコンポーネントが最も適切なテクノロジを備えている必要があるということです。これにより、作成、理解、および保守が容易になります。技術は過剰にすべきではなく(必要以上に複雑で費用がかかる技術を使用して)、その能力の限界にあるべきではないため、望ましい目標を達成するために技術的なゆがみが必要です。

それが「正規表現を嫌うのが流行りそう」な理由です。彼らは多くのことを行うことができますが、それを実現するために非常に読みにくいコーディングが必要な場合があります。実装のさまざまな拡張機能や制限により、理論上の単純さが多少低下することは言うまでもありません。レクサーは通常これを行わず、トークンを解析するためのシンプルで効率的な適切なテクノロジーです。トークンにCFパーサーを使用することは可能ですが、やり過ぎです。

レクサーにCF形式を使用しないもう1つの理由は、CFの全機能を使いたくなる可能性があるためです。しかし、それはプログラムの読みに関して構造上の問題を引き起こすかもしれません。

基本的に、意味が抽出されるプログラムテキストの構造のほとんどはツリー構造です。構文規則から構文解析文(プログラム)がどのように生成されるかを表します。セマンティクスは、構文規則を構成して構文解析ツリーを構築する方法から、構成手法(数学指向の同型)によって導出されます。したがって、ツリー構造は不可欠です。トークンが通常のセットベースのレクサーで識別されるという事実は、状況を変更しません。これは、通常で構成されたCFがCFを与えるためです(私は、文字のストリームをトークンのストリームに変換する通常のトランスデューサーについて大まかに話します)。

ただし、CFで構成されたCF(CFトランスデューサーを介して...計算は申し訳ありません)は、必ずしもCFを与えるわけではなく、物事をより一般的にする可能性がありますが、実際には扱いにくくなります。したがって、CFは使用できますが、レクサーには適切なツールではありません。

通常の言語とCFの主な違いの1つは、通常の言語(およびトランスデューサー)がさまざまな方法でほとんどすべての形式で非常にうまく構成するのに対し、CF言語(およびトランスデューサー)はそれ自体ではなく(いくつかの例外を除き)構成しません。

(通常のトランスデューサーには、一部の構文エラー処理手法の形式化など、他の用途がある場合があることに注意してください。)

BNFは、CF文法を表示するための特定の構文にすぎません。

EBNFはBNFの構文シュガーであり、通常の表記法の機能を使用して、BNF文法のより簡潔なバージョンを提供します。常に同等の純粋なBNFに変換できます。

ただし、通常の表記法はEBNFで使用されることが多く、字句要素の構造に対応する構文のこれらの部分を強調するためにのみ使用され、レクサーで認識される必要があります。しかし、それは絶対的なルールではありません。

要約すると、(プログラム構文の)言語のツリー指向の構造はCF文法でより適切に処理されますが、トークンのより単純な構造は、通常の言語のより単純なテクノロジーでより適切に分析されます。

AHRの回答も確認することをお勧めします

しかし、これは疑問を残します:なぜ木?

ツリーは構文を指定するための優れた基盤です。

  • 彼らはテキストに単純な構造を与えます

  • 上に示したように、数学的によく理解されているテクノロジー(準同型による構成)を使用して、その構造に基づいてセマンティクスをテキストに関連付けるのに非常に便利です。これは、数学的形式のセマンティクスを定義するための基本的な代数ツールです。

したがって、抽象構文木(AST)の成功が示すように、これは優れた中間表現です。多くの専門家(LLやLRなど)が使用する解析技術はCF文法のサブセットにのみ適用されるため、ASTは解析ツリーとは異なる場合が多いことに注意してください。これは、任意のCF文法を受け入れる(動的プログラミングに基づく)より一般的な構文解析テクノロジで回避できます。

プログラミング言語がCFではなく状況依存(CS)であるという事実についての陳述は恣意的であり、議論の余地があります。

問題は、構文とセマンティクスの分離が任意であることです。宣言または型の一致のチェックは、構文の一部またはセマンティクスの一部と見なされる場合があります。自然言語での性別と数の合意についても同じことが言えます。しかし、複数の一致が単語の実際の意味論的意味に依存する自然言語があり、そのため、構文にうまく適合しません。

表示セマンティクスでのプログラミング言語の多くの定義では、セマンティクスに宣言と型チェックが配置されています。Ira Baxterによって行われたように述べていますれたように、構文に必要な状況依存性を取得するためにCFパーサーがハッキングされているは、せいぜい状況の恣意的な見方です。一部のコンパイラではハックとして構成されている場合がありますが、そうである必要はありません。

また、CSパーサーが(ここで他の回答で使用されている意味で)構築が難しく、効率が悪いだけではありません。それらはまた、必要とされるかもしれない状況依存性の種類をはっきりと表現するには不十分です。また、プログラムのセマンティクスを導き出す、つまりコンパイルされたコードを生成するのに便利な構文構造(構文解析ツリーなど)を自然には生成しません。


はい、解析ツリーとASTは異なりますが、実際にはあまり役に立ちません。:この私の議論を参照してくださいstackoverflow.com/a/1916687/120163
アイラバクスター

@IraBaxter私はあなたに同意しませんが、あなたの投稿に対する明確な回答を下書きする時間は本当にありません。基本的に、あなたは実用的な見方をしています(そしてあなた自身のシステムを守っていると思います)。一部のシステムのように確定的なパーサーを使用するのではなく、一般的なCFパーサーを使用しているため(GLRが最も効率的ではない可能性があります)、これはさらに簡単です。私は、証明可能正しい変換、証明、複数の具体的表現にunparsingなど、正式に定義された治療に役立つ基準表現としてASTを考える
babou

「実用的」な見方が、それらが有用な点であまり変わらないと私が主張する理由です。そして、私は(アドホックAST)を使用することで「ほぼ正しい変換」が得られるとは信じていません。アドホックASTは、処理される言語の実際の文法と明確な関係はありません(そして、ここでは、はい、私のシステムは、「AST」がBNFと同等の同型である可能性があるという点で防御可能です)。アドホックのASTいけないGLRにあなたの異議(最も効率的ではないが)かなり無意味と思われる)、複数の具体的な表現」にunparseにあなたに追加の機能を与えるも、彼らは非決定的です。。。
アイラバクスター

だから実際、私は私のコメントに対するあなたの反対の部分を理解していません。あなたはその「きれいな答え」を書かなければならないでしょう。
Ira Baxter

@IraBaxterコメントは制約が厳しく、適切な回答を得ることができません(提案?)。「アドホック」は、AST Iが提唱する適切な修飾子ではありません。これは、参照構文である必要があります(場合によっては)。これは歴史的に真実であり、コンピュータサイエンスにおけるASTの概念の歴史と、解釈とともにソートされた代数の項(ツリー)としての形式システムの歴史の両方を見ると、両方とも当てはまります。ASTは参照フォームであり、派生フォームではありません。最新の校正システムと自動プログラム生成もご覧ください。他の人が設計した具体的な構文から作業しなければならないという事実に偏っています。
バブー

7

コンパイラーの分析部分が通常、字句分析フェーズと構文解析(構文分析)フェーズに分けられる理由はいくつかあります。

  1. シンプルなデザインが最も重要な考慮事項です。字句解析と構文解析を分離することで、これらのタスクの少なくとも1つを簡略化できることがよくあります。たとえば、構文単位としてコメントと空白を処理しなければならなかったパーサー。コメントと空白を想定できるものよりもかなり複雑で、字句解析器によってすでに削除されています。新しい言語を設計する場合、語彙と構文の問題を分離することで、全体的な言語設計をより簡潔にすることができます。
  2. コンパイラの効率が向上します。個別の字句アナライザーを使用すると、構文解析の仕事ではなく、字句タスクのみを処理する特殊な手法を適用できます。さらに、入力文字を読み取るための特殊なバッファリング技術により、コンパイラの速度を大幅に向上させることができます。
  3. コンパイラの移植性が向上しました。入力デバイス固有の特性は、字句解析器に限定することができます。

resource___ コンパイラ(第2版)-Alfred V. Aboコロンビア大学モニカS.ラムスタンフォード大学Ravi Sethi Avaya Jeffrey D. Ullmanスタンフォード大学

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.