2

コンパイラのレクサー/トークナイザーはどのように「意味を成す」のですか : a+++b? 次のように:

int a=0,b=0,x=0;
x = a+++b;

おそらく一般化されたサフィックスツリーを使用していると思いますが、もしそうなら、なぜ長いトークン ( ) が短いトークン ( ) の前に解釈され、その逆ではないのでしょうか? なぜそれが次のように解釈されるのかを意味します:+++

(a++) + b

ではない:

a + (++b)

?

私は自分である種のトークナイザーを書く必要があり、それについて疑問に思っていました。

4

2 に答える 2

0

lexer は通常貪欲です。つまり、トークンが別の (または同じ) トークンに一致する他の文字列よりも大きい文字列に一致する場合、より大きな文字列に一致します。

この例では、レクサーは最初に「a」文字に一致し、「識別子」(または「変数」)が潜在的なトークンであると考えます(「abstract」や「as」など、a 文字で始まる他のトークンも) )、その後、レクサーは次の文字 ("+") を読み取り、a+ は識別子ではなく、"abstract" でも "as" でもないため、"a" の候補の検索を停止し、それを次のようにトークン化します。識別子。

その後、彼は現在の記号として「+」を持ち、それに一致する潜在的なトークン (「+」、「++」、「+=」) について考えます。これは、レクサーが次の記号を続行しようとする「貪欲さ」のためです。 char を取得し、次の「+」を取得するため、一致できる唯一のトークンは「++」であると結論付けます (「+++」が有効なトークンである場合、次の記号が + の場合、レクサーは破棄する必要があります)。

次のステップでは、次の文字 (再び "+") を取り、可能なトークン ("+"、"++"、"+=") について考えます。彼は次の文字 ("b") を取り、"+ b" が任意のトークンの潜在的なプレフィックスではない場合、彼は次のトークンが "+" であると判断します。

次に、"b" (潜在的に識別子または任意の b 開始キーワード ("base"、"bool"、"break"、"byte")) を続行しますが、次の文字 (";") を読み取ると、レクサーはそれが識別子であると判断します。

したがって、レクサーは次のトークンを生成します

識別子 ++ + 識別子 ;

于 2013-10-01T20:12:11.277 に答える