「トークン化機構」、「パーサー」、「レクサー」の明確な定義と、それらが相互にどのように関連して使用されるかを探していますか?


151

「トークン化」、「パーサー」、「レクサー」とは何か、それらが互いにどのように関連しているのか(パーサーがトークナイザーを使用するか、その逆など)の明確な定義を探しています。データの宣言と定義を抽出するためにc / hソースファイルを処理するプログラムを作成する必要があります。

私は例を探していて、いくつかの情報を見つけることができますが、文法規則、解析ツリー、抽象構文ツリーなどの基本的な概念と、それらがどのように相互に関連するかを理解するのに本当に苦労しています。最終的にこれらの概念は実際のプログラムに格納する必要がありますが、1)それらはどのように見えるか、2)一般的な実装があります。

LexやYaccのようなこれらのトピックやプログラムについてウィキペディアを見てきましたが、コンパイラークラス(EEメジャー)を一度も経験したことがないので、何が起こっているのかを完全に理解するのは難しいと感じています。

回答:


166

トークナイザーは、通常、空白(タブ、スペース、改行)を探すことにより、テキストのストリームをトークンに分割します。

レクサーは基本的にトークナイザーですが、通常はトークンに追加のコンテキストを付加します。このトークンは数値であり、そのトークンは文字列リテラルであり、他のトークンは等価演算子です。

パーサーは、レクサーからトークンのストリームを受け取り、それを元のテキストで表される(通常は)プログラムを表す抽象構文ツリーに変換します。

最後にチェックしたところ、このテーマに関する最も優れた本は、通常「ドラゴンブック」としてのみ知られる「コンパイラ:原則、テクニック、およびツール」でした。


8
間違いなく「ドラゴンブック」は良い本ですが、読者がCSを十分に理解している必要があります。より実用的な魅力のある本は、ロナルド・マックによる「コンパイラーとインタープリターの作成」、「モダン・コンパイラーの実装」、アンドリュー・アペルです。「コンパイラー構築」、ニクラウス・ワース。Pat Cerryによる「C#とJavaを使用したコンパイル」および「コンパイラーとコンパイラージェネレーター:C ++の概要」そしてもちろん、Terrence Parrによる「The Definitive ANTLR Reference」。
Andre Artus

5
念のために言っておきますが、私はあなたの推薦をたたきません。「ドラゴンブック」はコンパイラテックに関する私の最初の本でしたが、たとえば、数時間で読める本であるワースの本と比較するのは大変でした。それが手に入れることができる唯一の本だったので、当時、私にはいくつかの選択肢がありました(AmazonとWWWより前の1991年です)。それと、ジャックW.クレンショーが作成したテキストファイルのコレクションを「LET'S BUILD A COMPILER」と呼びました(ジャックに感謝します!)。これはまだ原則をより完全に理解するための本ですが、ほとんどのプログラマーは実用的な導入を必要としています。
Andre Artus

10
パーサーが/定義により/抽象構文木を生成することには同意しません。パーサーは、あらゆる種類の異なる出力を生成できます。たとえば、パーサーがいくつかのビルダーインターフェイスへの呼び出しのシーケンスを生成することは一般的です-Gang of Fourパターンの本のビルダーパターンを参照してください。重要な点は、パーサーがトークンのシーケンスを分析して、シーケンスが一部の(通常はコンテキストフリーの)文法に準拠しているかどうかを判断し、シーケンスの文法構造に基づいて出力を生成できることです。
セオドアノーベル2013

2
「Let's Build a Compiler」はこちら:compilers.iecc.com/crenshaw。私はここからリンクを見つけました:prog21.dadgum.com/30.html
Roger Lipscombe

1
@Pithkos:これらが唯一の制約である場合、関数は名前のない(数学)ドメインで入力を取り、別の名前のないドメイン(F(X)-> Yなど)で生成および出力することだけを説明しましたこれは「関数」としか呼ばれません。Xのドメインが<StreamOfCharacter、Grammar>であり、Yのドメインが文法の形状を反映するプロパティを持つTreeであると主張する場合、F(X、G)-> Tは、パーサー。多くの場合、Gは頻繁に変更されないため、FをGに関してカレー化します。したがって、F [G](X)-> Tは、パーサーとして一般的に見られるものです。
Ira Baxter

18

例:

int x = 1;

レクサーまたはトークナイザーはそれをトークン「int」、「x」、「=」、「1」、「;」に分割します。

パーサーはこれらのトークンを取得し、それらを使用して何らかの方法で理解します。

  • 声明があります
  • 整数の定義です
  • 整数は「x」と呼ばれます
  • 「x」は値1で初期化する必要があります

9
レクサーは、「int」、「=」、および「;」に注意します。「x」は識別子の名前または何か、値「x」、「1」は整数または数値、値「1」です。トークナイザーは必ずしもそれをしません。
David Thornley

5

字句解析器とトークナイザは基本的に同じものであり、テキストを構成要素(「トークン」)に分割すると言います。次に、パーサーは文法を使用してトークンを解釈します。

ただし、正確な用語の使い方にこだわる必要はありません。テキストのかたまりを解釈するアクションを説明するために、しばしば「解析」を使用します。


1
PEGパーサーを使用すると、トークナイザーとパーサーの違いがさらに不明確になります。
Andre Artus

0

与えられた答えに追加

  • Tokenizerはコメント削除し、トークンのみをレクサーに返します。
  • レクサーは、それらのトークン(変数/関数)のスコープ定義します
  • 次に、パーサーはコード/プログラム構造を構築します

1
こんにちは@downvoter、なぜ実際に反対投票したのか詳しく説明していただけますか?
Koray Tugay

1
私は反対投票者ではありませんが、あなたの答えが正しくないようであったため、反対投票が行われた可能性があります。トークナイザーはノイズを除去する可能性がありますが(通常は空白ですが、コメントも含まれます)、レクサーにフィードされないことがよくあります。DFAベースのレクサーはトークン化し、トークンが何であるかを識別します(たとえば、数値、文字列、識別子だけでなく、空白またはコメントも)。パーサー。
Lucero、

1)「レクサー」と「トークン化機能」の見た目の違いがわかりません。私は50以上の言語用のパーサーを構築しましたが、ソーステキストをアトムに分割する2つの別個のメカニズムはありませんでした。2)コンパイルしている場合、コメントと空白を削除することはレクサーで意味があります。ソースからソースへの変換ツールを構築している場合、変換後のテキストに再表示する必要があるため、コメントを失うことはありません。したがって、常にコメントを削除することは間違っています。空白をどのように維持するかについて議論することができます。...
Ira Baxter

1
... [私が作成したツール(私の経歴を参照)は、変換されたコードでそれらを再現するのに十分な忠実度で両方をキャプチャします。さらに進んで、アトムのフォーマットをキャプチャします。これには、文字列で使用される引用符や数値の基数/先頭のゼロのカウントなどの変なものも含まれます。これらはすべて、ユーザーが変換結果を拒否するのを防ぐためです。したがって、見落としているのは、レクサーが情報を必ずしも削除するだけでなく、実際には、生のトークンを超えて情報を取得する必要がある場合です] ....
Ira Baxter

... 3)レクサーは、構文のあいまいさを処理するのに苦労する絶望的に扱いにくいパーサーでのみ「スコープ」を定義します。CおよびC ++パーサーは標準的な例です。stackoverflow.com/a/1004737/120163で私の議論を参照してください)。それを(醜い)方法で行う必要はありません。だから私はあなたの答えが単に見当違いであると思います。
Ira Baxter
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.