トークンと語彙素の違いは何ですか?


86

Aho UllmanとSethiによるコンパイラの構築では、ソースプログラムの文字の入力文字列は、論理的な意味を持つ文字のシーケンスに分割され、トークンと呼ばれ、語彙素はトークンを構成するシーケンスであるとされています。基本的な違いは何ですか?

回答:


118

CompilersPrinciples、Techniques、&Tools、2nd Ed。(WorldCat)を使用して、Aho、Lam、Sethi、Ullman、別名The Purple Dragon Book

語彙素pg。111

語彙素は、トークンのパターンに一致するソースプログラム内の文字のシーケンスであり、字句解析プログラムによってそのトークンのインスタンスとして識別されます。

トークンページ 111

トークンは、トークン名とオプションの属性値で構成されるペアです。トークン名は、特定のキーワードや識別子を示す入力文字のシーケンスなど、一種の語彙単位を表す抽象的な記号です。トークン名は、パーサーが処理する入力シンボルです。

パターンページ 111

パターンは、トークンの語彙素がとることができる形式の説明です。トークンとしてのキーワードの場合、パターンはキーワードを形成する文字のシーケンスです。識別子やその他のトークンの場合、パターンはより複雑な構造であり、多くの文字列と一致します。

図3.2:トークンの例pg.112

[Token]       [Informal Description]                  [Sample Lexemes]
if            characters i, f                         if
else          characters e, l, s, e                   else
comparison    < or > or <= or >= or == or !=          <=, !=
id            letter followed by letters and digits   pi, score, D2
number        any numeric constant                    3.14159, 0, 6.02e23
literal       anything but ", surrounded by "'s       "core dumped"

レクサーとパーサーとのこの関係をよりよく理解するために、パーサーから始めて、入力に逆戻りします。

パーサーの設計を容易にするために、パーサーは入力を直接処理するのではなく、レクサーによって生成されたトークンのリストを取り込みます。我々のようなトークンを参照して、図3.2におけるトークンの列を見るとifelsecomparisonidnumberliteral。これらはトークンの名前です。通常、レクサー/パーサーの場合、トークンは、トークンの名前だけでなく、トークンを構成する文字/記号、およびトークンを構成する文字列の開始位置と終了位置を保持する構造です。エラー報告、強調表示などに使用される開始位置と終了位置。

これで、レクサーは文字/記号の入力を受け取り、レクサーのルールを使用して、入力された文字/記号をトークンに変換します。現在、レクサー/パーサーを使用する人々は、頻繁に使用するものに対して独自の言葉を持っています。トークンを構成する一連の文字/記号として考えるのは、レクサー/パーサーを使用する人々が語彙素と呼ぶものです。したがって、語彙素を見るときは、トークンを表す文字/記号のシーケンスを考えてみてください。比較例では、文字/記号のシーケンスは、<or>またはelseorなどの異なるパターンにすることができます3.14

2つの関係を考える別の方法は、トークンは、入力からの文字/記号を保持する語彙素と呼ばれるプロパティを持つパーサーによって使用されるプログラミング構造であるということです。ここで、コード内のトークンのほとんどの定義を見ると、トークンのプロパティの1つとして語彙素が表示されない場合があります。これは、トークンがトークンと語彙素を表す文字/記号の開始位置と終了位置を保持する可能性が高いためです。入力が静的であるため、必要に応じて文字/記号のシーケンスを開始位置と終了位置から導出できます。


12
口語的なコンパイラの使用法では、人々は2つの用語を同じ意味で使用する傾向があります。必要に応じて、正確な区別ができます。
Ira Baxter

純粋にコンピュータサイエンスの定義ではありませんが、これは、語彙セマンティクスの概要から 関連する自然言語処理からのものですan individual entry in the lexicon
Guy Coder

絶対に明確な説明。これが天国で物事を説明する方法です。
Timur Fayzrakhmanov

素晴らしい説明。もう1つ疑問があります。解析段階についても読みました。パーサーはトークンを検証できないため、パーサーは字句アナライザーからトークンを要求します。パーサーの段階で簡単な入力を行い、パーサーがレクサーにトークンを要求するのはいつかを説明してください。
プラザンナサスネ

@PrasannaSasneSOcan you please explain by taking simple input at parser stage and when does parser asks for tokens from lexer.はディスカッションサイトではありません。それは新しい質問であり、新しい質問として尋ねる必要があります。
Guy Coder

36

ソースプログラムが字句解析プログラムに入力されると、文字を語彙素のシーケンスに分割することから始まります。次に、語彙素はトークンの構築に使用され、語彙素はトークンにマップされます。myVarという変数は、< id、 "num">を示すトークンにマップされます。ここで、 "num"は、シンボルテーブル内の変数の場所を指している必要があります。

簡単に言えば:

  • 語彙素は、文字入力ストリームから派生した単語です。
  • トークンは、トークン名と属性値にマップされた語彙素です。


例は次のとおりです
。x= a + b * 2
語彙素を生成します:{x、=、a、+、b、*、2}
対応するトークン:{< id、0>、<=>、< id、1 >、<+>、< id、2>、<*>、< id、3>}


2
<id、3>であるはずですか?2は識別子ではないため
Aditya 2018

しかし、xが識別子であるとはどこに書かれていますか?つまり、シンボルテーブルは、特定のエントリとして「名前」= x、「タイプ」=「識別子(id)」、ポインタ=「0」を持つ3列のテーブルであるということですか?その場合、「名前」のような他のエントリが必要です。 = while、 'type' = 'keyword'、pointer = '21' ??

8

a)トークンは、プログラムのテキストを構成するエンティティの記号名です。たとえば、キーワードの場合はif、任意の識別子の場合はidです。これらは字句解析器の出力を構成します。5

(b)パターンは、入力からの文字のシーケンスがいつトークンを構成するかを指定するルールです。たとえば、トークンifのシーケンスi、f、およびトークンIDの文字で始まる英数字のシーケンス。

(c)語彙素は、パターンに一致する(したがって、トークンのインスタンスを構成する)入力からの文字のシーケンスです。たとえば、ifはifのパターンに一致し、foo123barはidのパターンに一致します。


8

LEXEME-トークンを形成するPATTERNと一致する文字のシーケンス

PATTERN-トークンを定義する一連のルール

TOKEN-プログラミング言語の文字セットに対する意味のある文字のコレクション例:ID、定数、キーワード、演算子、句読点、リテラル文字列


7

語彙素-語彙素は、トークンのパターンに一致するソースプログラム内の文字のシーケンスであり、字句解析プログラムによってそのトークンのインスタンスとして識別されます。

トークン-トークンは、トークン名とオプションのトークン値で構成されるペアです。トークン名は語彙単位のカテゴリです。一般的なトークン名は次のとおりです。

  • 識別子:プログラマーが選択する名前
  • キーワード:すでにプログラミング言語にある名前
  • 区切り文字(句読点とも呼ばれます):句読文字とペア区切り文字
  • 演算子:引数を操作して結果を生成する記号
  • リテラル:数値、論理、テキスト、参照リテラル

プログラミング言語Cでこの式を考えてみましょう。

合計= 3 + 2;

トークン化され、次の表で表されます。

 Lexeme        Token category
------------------------------
sum      |    Identifier
 =       |    Assignment operator
 3       |    Integer literal
 +       |    Addition operator
 2       |    Integer literal
 ;       |    End of statement

5

字句アナライザー(スキャナーとも呼ばれます)の動作を見てみましょう

式の例を見てみましょう:

INPUT : cout << 3+2+3;

FORMATTING PERFORMED BY SCANNER :  {cout}|space|{<<}|space|{3}{+}{2}{+}{3}{;} 

ただし、実際の出力ではありません。

スキャナーは、入力がなくなるまで、ソースプログラムテキストの語彙素を繰り返し探します。

語彙素は、文法に存在する有効な端末の文字列を形成する入力の部分文字列です。すべての語彙素は、最後に説明されているパターンに従います(読者が最後にスキップする可能性のある部分)

(重要なルールは、次の空白が検出されるまで、有効な端末の文字列を形成する可能な限り長いプレフィックスを探すことです...以下で説明します)

語彙素:

  1. カウト
  2. <<

(「<」も有効な端末文字列ですが、上記のルールでは、スキャナーから返されるトークンを生成するために、語彙素「<<」のパターンを選択する必要があります)

  1. 3
  2. +
  3. 2
  4. ;

トークンスキャナーが(有効な)語彙素を見つけるたびに、トークンは一度に1つずつ返されます(パーサーから要求された場合はスキャナーによって)。スキャナーは、まだ存在しない場合は、語彙素を見つけると、トークンを生成するために、シンボルテーブルエントリ(属性:主にトークンカテゴリとその他のいくつか)を作成します。

「#」はシンボルテーブルエントリを示します。わかりやすくするために上記のリストの語彙素番号を指摘しましたが、技術的にはシンボルテーブルの実際のレコードのインデックスである必要があります。

次のトークンは、上記の例で指定された順序でスキャナーからパーサーに返されます。

  1. <識別子、#1>

  2. <オペレーター、#2>

  3. <リテラル、#3>

  4. <オペレーター、#4>

  5. <リテラル、#5>

  6. <オペレーター、#4>

  7. <リテラル、#3>

  8. <パンクチュエーター、#6>

違いがわかるように、トークンは、入力の部分文字列である語彙素とは異なり、ペアです。

そして、ペアの最初の要素はトークンクラス/カテゴリです

トークンクラスは以下のとおりです。

  • キーワード
  • 識別子
  • リテラル
  • パンクチュエーター
  • オペレーター
  • そしてもう1つ、スキャナーは空白を検出し、それらを無視し、空白のトークンをまったく形成しません。すべての区切り文字が空白であるわけではありません。空白は、スキャナーがその目的で使用する区切り文字の1つの形式です。入力内のタブ、改行、スペース、エスケープ文字はすべて、まとめて空白区切り文字と呼ばれます。他の区切り文字はほとんどありません ';' '、' ':'など。トークンを形成する語彙素として広く認識されています。

    ここで返されるトークンの総数は8ですが、語彙素に対して作成されるシンボルテーブルエントリは6つだけです。語彙素も合計8つです(語彙素の定義を参照)

    ---この部分はスキップできます

    A ***pattern*** is a rule ( say, a regular expression ) that is used to check if a string-of-terminals is valid or not

    If a substring of input composed only of grammar terminals is following the rule specified by any of the listed patterns , it is validated as a lexeme and selected pattern will identify the category of lexeme, else a lexical error is reported due to either (i) not following any of the rules or (ii) input consists of a bad terminal-character not present in grammar itself.

    for example :
    
    1. No Pattern Exists : In C++ , "99Id_Var" is grammar-supported string-of-terminals but is not recognised by any of patterns hence lexical error is reported .
    
    2. Bad Input Character : $,@,unicode characters may not be supported as a valid character in few programming languages.`
    

    5

    語彙素-語彙素は、プログラミング言語の最下位レベルの構文単位である文字列です。

    トークン-トークンは、語彙素のクラスを形成する構文カテゴリです。つまり、語彙素が属するクラスは、キーワードや識別子などです。字句解析プログラムの主要なタスクの1つは、語彙素とトークンのペアを作成することです。つまり、すべての文字を収集します。

    例を見てみましょう:-

    if(y <= t)

    y = y-3;

    語彙素トークン

    キーワードの場合

    (左括弧

    y識別子

    <=比較

    t識別子

    )右括弧

    y識別子

    =アセスメント

    y識別子

    _算術

    3整数

    ;                                    セミコロン

    語彙素とトークンの関係

    語彙素とトークンの関係


    4

    トークン:(キーワード、識別子、句読文字、複数文字の演算子)の種類は、単純にトークンです。

    パターン:入力文字からトークンを形成するためのルール。

    語彙素:トークンのパターンと一致するソースプログラム内の文字のシーケンス。基本的に、それはトークンの要素です。


    3

    トークン: トークンは、単一の論理エンティティとして扱うことができる文字のシーケンスです。典型的なトークンは、
    1)識別子
    2)キーワード
    3)演算子
    4)特殊記号
    5)定数です。

    パターン:同じトークンが出力として生成される入力内の文字列のセット。この文字列のセットは、トークンに関連付けられたパターンと呼ばれるルールによって記述されます。
    語彙素:語彙素は、トークンのパターンと一致するソースプログラム内の文字のシーケンスです。


    1

    語彙 素語彙素は、トークン内の一連の文字(英数字)であると言われています。

    トークン トークンは、単一の論理エンティティとして識別できる文字のシーケンスです。通常、トークンはキーワード、識別子、定数、文字列、句読記号、演算子です。数字。

    パターンパターン と呼ばれるルールによって記述された文字列のセット。パターンは、トークンになり得るものを説明し、これらのパターンは、トークンに関連付けられた正規表現によって定義されます。


    1

    CSの研究者は、数学の研究者と同様に、「新しい」用語を作成するのが好きです。上記の答えはすべて素晴らしいですが、どうやら、トークンと語彙素を区別する必要はそれほどありません。それらは同じことを表す2つの方法のようなものです。語彙素は具体的です-ここでは文字のセットです。一方、トークンは抽象的です。通常、語彙素のタイプとその意味値を参照します。ちょうど私の2セント。


    0

    字句解析プログラムは、文字のシーケンスを取得して、正規表現に一致する語彙素を識別し、さらにそれをトークンに分類します。したがって、語彙素は一致する文字列であり、トークン名はその語彙素のカテゴリです。

    たとえば、入力が「int foo、bar;」の識別子の以下の正規表現について考えてみます。

    文字(文字|数字| _)*

    ここでは、fooおよびbarので、両方の語彙素であるが、1つのトークンとして分類された正規表現に一致するID、すなわち識別子。

    また、次のフェーズ、つまり構文アナライザーは、語彙素ではなくトークンについて知る必要があることに注意してください。


    -2

    語彙素は基本的にトークンの単位であり、基本的にトークンに一致する文字のシーケンスであり、ソースコードをトークンに分割するのに役立ちます。

    例:ソースがある場合はx=b、その語彙素は次のようになりx=bおよびトークンは次のようになり<id, 0><=><id, 1>


    答えはもっと具体的にする必要があります。例が役立つかもしれません。
    zverev Evgeniy 2016
    弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
    Licensed under cc by-sa 3.0 with attribution required.