2016-04-17 7 views
2

私は現在コンパイラを書いており、私はレクサーフェーズに入っています。レクサーの出力

私はレクサーが入力ストリームをトークン化することを知っています。

ただし、以下の流れを考慮してください。

int foo = 0; 

レクサーの出力は次のようになります。Keywordletterletterletterequalsdigitsemicolon?パーサーは、letterletterletterを識別子に減らしますか?

答えて

2

"letter"を中間ステップとして持つことは実際には得られません。代わりに "foo"がおそらく識別子になるはずです。さもなければ、あなたはintを「レターレターレター」としても分かりません。

+0

助けてくれてありがとう – Techworld

2

一般的なケースでは簡単な答えはありません。

通常、言語の文法ができる場合レクサーは識別子あるいはタイプ変数のような「より高いレベル」の要素を特定持つことが容易です。文法がより動的でトークンの解釈が内部状態に依存する場合は、パーサーがパーサに解釈をポーズする方が簡単な場合があります。そうしないと、レクサーとパーサー間の通信が過度に複雑になる可能性があります。経験則として

(例えばint型は別の内の1つの場所と有効な変数名を入力し、第三のケースでの言語のキーワードであるlanguateを検討):レクサーを保つすべての作業をやらせますレクサーとパーサーの間の複雑さを増やすことなく、簡単に文法を理解できます。

+0

このチップをいただきありがとうございます。 – Techworld

4

一般的には、あなたのレクサーは、言語要素含まストリームの構造体生成する必要があります。これらの構造体は、語彙素のタイプでマークされなければならないなどの演算子、識別子、キーワード、コメントを、とに関連するコンテンツを運びますそれが表す語彙素のタイプ。

良いレポーティングを可能にするには、各レクメムに開始行と列、エンドラインの行と列(複数の行にまたがるレクメム)、および元のソースファイルに関する情報が含まれているとよいメインファイルと同様に)。

可変内容(数値、識別子など)を含む言語要素の場合、構造体には可変内容が含まれている必要があります。

コンパイルまたはプログラム解析のために、レクサーは空白とコメントを捨てることができます。コードを解析/変更する場合は、コメントを取得する必要があります。

出力例は参考になります。 OPの変形例:

/* My test file */ 

int foo 
    = 0; // a declaration 

...DMSのCフロントエンドは、(これは複雑なレクサーを設計するときに持って、本当に便利デバッグ出力である)以下の語彙素を生成します。

C:\DMS\Domains\C\GCC4\Tools\Lexer\Source>run ../domainlexer C:\temp\test.c 
Lexer Stream Display 1.5.1 
Using encoding Unicode-UTF-8?ANSI +CRLF +1 /^I 
!! Lexer:ResetLexicalModeStack 
!! after Lexer:PushLexicalMode: 
Lexical Mode Stack: 
1 C 
File "C:/temp/test.c", line 1: /* My test file */ 
File "C:/temp/test.c", line 2: 
File "C:/temp/test.c", line 3: int foo 
!! Lexer:GotoLexicalMode 2 CMain 
!! Lexeme @ Line 3 Col 1 ELine 3 ECol 4 Token 23: 'int' [VOID]=0000 
    <<< PreComments: 
Comment 1 Type 1 Line 1 Column 1 `/* My test file */' 
!! Lexeme @ Line 3 Col 4 ELine 3 ECol 5 Token 2: whitespace [VOID]=0000 
!! Lexeme @ Line 3 Col 5 ELine 3 ECol 8 Token 210: IDENTIFIER [STRING]=`foo' 
File "C:/temp/test.c", line 4:  = 0; // a declaration 
!! Lexer:GotoLexicalMode 1 C 
!! Lexeme @ Line 3 Col 8 ELine 4 ECol 5 Token 2: whitespace [VOID]=0000 
!! Lexer:GotoLexicalMode 2 CMain 
!! Lexeme @ Line 4 Col 5 ELine 4 ECol 6 Token 113: '=' [VOID]=0000 
!! Lexeme @ Line 4 Col 6 ELine 4 ECol 7 Token 2: whitespace [VOID]=0000 
!! Lexeme @ Line 4 Col 7 ELine 4 ECol 8 Token 138: INT_LITERAL [NATURAL]=0 
File "C:/temp/test.c", line 5: 
!! Lexeme @ Line 4 Col 8 ELine 4 ECol 9 Token 98: ';' [VOID]=0000 
    >>> PostComments: 
Comment 1 Type 2 Line 4 Column 10 `// a declaration' 
File "C:/temp/test.c", line 5: 
File "C:/temp/test.c", line 6: 
File "C:/temp/test.c", line 7: 
!! Lexer:GotoLexicalMode 1 C 
!! Lexeme @ Line 4 Col 26 ELine 7 ECol 1 Token 2: whitespace [VOID]=0000 
!! Lexeme @ Line 7 Col 1 ELine 7 ECol 1 Token 4: end_of_input_stream [VOID]=0000 
!! Lexer:GotoLexicalMode 2 CMain 
!! Lexeme @ Line 7 Col 1 ELine 7 ECol 1 Token 0: EndOfFile 
11 lexemes processed. 
0 lexical errors detected. 

C:\DMS\Domains\C\GCC4\Tools\Lexer\Source> 

メイン出力はラインはをマークされています!であり、それぞれはレクサーによって生成される字句構造体の内容を表す。各語彙素を運ぶ:

  • ソースファイルの位置情報(ここではメインファイルのため、「test.cの」は、それがデバッグ出力が少し読みやすくするために印刷されていない)
  • 「トークン数を
  • トークンによって運ばれる値のタイプ:[VOID]は「なし」を意味し、[STRING]はトークン値を運ぶことを意味し、 [NATURAL]は整数値などを運ぶことを意味します。
  • precomments:トークンの前のコメント。これは古典的なレクサーにとっては珍しいことですが、ソースコードを変換しようとする場合には必要です。あなたはコメントを失うことはできません!プリコンパイルがトークンに添付されていることに注意してください。コメントは意味的に意味がないため、をどこに置くべきかを論じることができます。これが私たちの特別な選択です。
  • postcomment:コメントは、それに属するトークンであるに従います。

最後のトークンEndOfFileは、すべてのDMSレクサーで暗黙的に定義されています。

このデバッグトレースは、レキシカルモード間のレクサーの遷移も記録します(多くのレクサージェネレータには、言語のさまざまな部分をレックスする複数のモードがあります)。読み込まれたソース行を示します。

+0

私はそれらのdownvotersを愛しています。なぜこれがOPの質問に正確に答えることができなかったのかについての発言なしにヒットして実行してください。 –

関連する問題