正規表現は、トークン化中に維持する必要がある状態/コンテキストがあるため、正しく取得するのが難しくなります。入力を 1 文字ずつ読み取り、手動でトークンを作成することをお勧めします。
C の場合は次のようになります (C++ については後で詳しく説明します)。
表示された場合は/
、先を見る必要があり、別の がある場合/
は、行末まですべてをスキップします。
/
の後に が続く場合は*
、別の まですべてをスキップします*
。次の*
char がそうでない場合は/
、 までスキップに戻り、オープニングとクロージング*
が一致したときに終了します。/*
*/
そのようなもので、すべてのコメントをスキップします。
または/
が続いていない場合は、 とを区別するために が続いているかどうかをさらに確認する必要があります。/
*
=
/
/=
これらのいずれかが表示された場合、それはトークンです: ,;?:()[]{}
。
が表示された場合は、 または のいずれか!
になる可能性があるため、先を見る必要があります。
が表示された場合は、 または のいずれかになる可能性があるため、先を見る必要があります。
が表示された場合は、 または のいずれかになる可能性があるため、先を見る必要があります。
が表示された場合は、 または のいずれかになる可能性があるため、先を見る必要があります。
が表示された場合は、 または のいずれかになる可能性があるため、先を見る必要があります。!
!=
*
*
*=
%
%
%=
^
^
^=
~
~
~=
表示される場合は、またはまたは+
のいずれかになる可能性があるため、先を見る必要があります。+
++
+=
表示された場合は、またはまたはまたは-
のいずれかになる可能性があるため、先を見る必要があります。-
--
-=
->
表示された場合は、またはまたはまたは<
のいずれかになる可能性があるため、先を見る必要があります。
表示された場合は、またはまたはまたはのいずれかになる可能性があるため、先を見る必要があります。<
<=
<<
<<=
>
>
>=
>>
>>=
表示される場合は、またはまたは&
のいずれかになる可能性があるため、先を見る必要があります。
表示される場合は、またはまたはのいずれかになる可能性があるため、先を見る必要があります。&
&&
&=
|
|
||
|=
L
(または小文字の ) が表示されている場合は、リテラル文字または文字列定数またはl
を開始できるため、先読みする必要があります。それ以外の場合は、何らかの識別子の開始です。L'c'
L"string"
_
または ASCII 文字の from a
toz
または from A
toが表示された場合Z
、それは何らかの識別子の始まりです。この後に任意の数のアンダースコア、文字、または 10 進数を続けることができます。この方法で解析された識別子は、、、、、などの予約済みキーワードのセットに対してさらにチェックする必要がint
あります。const
if
switch
0
からまでの 10 進数が表示される場合は、9
複数のオプションがあります。8 進整数定数、10 進整数定数、16 進整数定数、浮動小数点定数です。上記と同様に、それらを解析する方法を理解できるはずです。定数には、、、、、および の接尾辞を付けることができることにU
注意UL
しULL
てL
ください。LL
F
表示される場合は、またはまたは のようなもの.
になる可能性があるため、先を見る必要があります。.
...
.5
リテラル文字または文字列定数の解析とトークン化については説明しません。内部にはエスケープ シーケンスなどのロジックがいくつかあります。
現在、C++ では、(解析の拡張)、(解析の拡張)、(解析の拡張) などの追加の::
解析:
を.*
行う必要があります。.
->*
-
new
virtual
and
bitor
not_eq
そして、C++ には驚きがあります。テンプレートの山かっこは、間にスペースを入れずに組み合わせることができるようになりました。
X<Y<Z> >
合法的に次のように書けるようになりました:
X<Y<Z>>
>>
パーサーは、最後のテンプレートが 2 つの別々のであることを理解するために、このテンプレート ビジネスを十分に理解する必要があり>
ます。
いくつかのプリプロセッサ関連のトークン (たとえば#
and ##
、include
、ifdef
、if
などundef
) と醜いトライグラフ シーケンスもあります。そしてもちろん、 との行連結があり\
ます。
これは楽しい小さな (またはそれほど少なくない) プロジェクトであり、特に受け入れられる入力の種類を制限する場合は、それほど手間をかけずに実行できます。
いずれにせよ、実際にはプロセスにいくつかのステート マシンを実装する必要がありますが、それらがどれほど単純であっても (ほとんどのマシンは単純になります)。