次: , 前: Pattern Matching, 上: Pattern Matching


3.6.1 文字

いくつかの文字はFlexにとって特別の意味があり、 その文字を単独で使ったのでは、 その文字自体を表すことができません。 以下に、 Flexにおける特殊文字とその意味を表にして示します。


文字
Flexによる解釈
.
ピリオドは改行(`\n')以外の任意の文字を表します。
\
バックスラッシュはエスケープ文字です。 エスケープ・シーケンスはANSI Cのものと同一です。
[ ]
角括弧[ ]は複数の文字を文字クラスにグループ化します。 詳細については、 See Flexにおける文字のグループ化
^
文字クラスの内部では^は否定を意味します。 詳細については、 See Flexにおける文字のグループ化。 文字クラスの外部では、 ^は行の先頭を意味し、 ルールの先頭にのみ置くことができます。 例を以下に示します。
[^AB]
否定クラスです。
^foo
行の先頭にある`foo'という文字の並びにのみマッチします。
foo^
この場合、 `^'は普通の文字であるとみなされます。 このような時には、 希望どおりの結果が確実に得られるようにするために、 特別な意味を持つ文字の前にバックスラッシュ`\'を置くのが良いでしょう。 このような文字の並びをエスケープ・シーケンスと呼びます。 エスケープ・シーケンスについてはこの節の最後で説明します。

-
ハイフンは文字クラスの内部において文字の範囲を表します。 文字クラスの外部では、 ハイフンはそれ自身を表します。 詳細については、 See Flexにおける文字のグループ化
{ }
大括弧{ }は、 定義の参照、複数行のアクションの囲み、またはある範囲にわたる繰り返しの定義を行います。 例を挙げると、 定義FOOがあって、 それをルールの中で参照したい場合に{FOO}を使います。

与えられたパターンのある範囲にわたる繰り返しを定義するには、 以下のような`{ repetition list }'を使います。

               %%
               
               
               
               f{2,5}  /* fの2回以上5回以下の繰り返し */
                       /* にマッチ                      */
               f{2,}   /* fの2回以上の繰り返しにマッチ */
               f{2}    /* fの2回の繰り返しにマッチ     */
          

この用法の解釈において、 FlexとLexの間にはいくつかの相違点があります。 詳細については、 Flex and POSIXを参照してください。

( )
丸括弧( )を使って優先順位を変更することができます。 また、 定義が展開される時には、 その定義は暗黙のうちに丸括弧( )で囲まれることに注意してください。1 このため、 Lexとは非互換なところがでてきます。 この点については、 Flex and POSIXDefinitionsで説明しています。
""
二重引用符記号は文字列を表します。 引用符の内側の文字列だけがマッチの対象になります。 したがって、
               %%
               "string"
          

"string"にではなく、 stringにマッチします。

/
スラッシュは後続コンテキスト(trailing context)を設定します。 これは、 あるパターンの後ろに特定の文字の並びが続く場合のみ、 そのパターンを認識したいという状況です。 つまり、 スラッシュ`/'は「ルック・アヘッド(その先を見る)」演算子として機能するということです。 例を挙げると、
abcDEF
`abcDEF' を認識します。
abc/DEF
`abc'の後ろに`DEF'が続く場合に限り、 `abc'を認識します。 `DEF'の部分は、 あたかもまだ読まれてはいないかのように扱われ、 マッチの対象になりません。

注:1つのルールの中では`/'は1つだけ許されます。 つまり、

               abc/def/hijkl
          

は不正です。

< >
かぎ括弧< >はスタート状態を参照します。 また、 EOFシンボル(`<<EOF>>')にも使われます。 完全な説明については、 Start StatesEnd-Of-File Rulesを参照してください。
? + *
`?'、`+'、`*'は、 ある正規表現が現れることのできる回数を設定します。 `?'は0回もしくは1回 (その正規表現が現れることは必須ではないということ) を意味します。 `+'は1回以上を意味します。 `*'は0回以上を意味します。 例えば、
a?
0個もしくは1個のaにマッチします。
a+
1個以上のaにマッチします。
a*
0個以上のaにマッチします。
(ABC)+
`ABC'という文字の並びが1回以上続くものにマッチします。
[abQrS]?
0個もしくは1個の、 (5つの文字`abQrS'から構成される) この文字クラスのメンバにマッチします。 文字クラスに関する詳細については、 Flexにおける文字のグループ化を参照してください。
{NUM}*
0個以上のNUMにマッチします。 ここでのNUMは定義です。 定義に関する詳細については、 Definitionsを参照してください。

|
OR演算子、 および、 特別なアクションを表します。 例えば、
                  apples|oranges
          

applesもしくはorangesのいずれかにマッチし、

               apples         |
               oranges        printf("fruit!\n");
          

は、 applesorangesの両方に対して同一のアクションを実行します。

$
ドル記号は行末を意味します。 例えば、
                  end$
          

はその直後が行末である場合にのみ`end'という文字の並びにマッチします。 これは、 後ろに続くのが行末のマーカである場合のみ`end'にマッチする

                  end/\n
          

とまったく同じです。

こうした文字のいずれかをその文字自身として表したい場合には、 引用符で囲むか、 (後に示す表で説明する) エスケープ・シーケンスとして表さなければなりません。

Flexには3種類のエスケープ・シーケンスがあります。 バックスラッシュ`\'に続けて8進数を使うもの、 `\x'に続けて16進数を使うもの、 `\letter'という表記法によってある1文字、 または、 特別な表示不可の文字を表すものの3つです。 Cをよく知っている人であれば、 この3つがANSI Cのエスケープ・シーケンスであることに気がつくことでしょう。 数値によるエスケープ・シーケンスは、 100パーセント移植性があるわけではなく、 保守を困難にするので、 避けるべきです。

以下に、 文字の使用に関する要約を示します。 この表中では、 `c'が単一の文字を、 `NNN'が8進定数を、 `HH'が16進定数を表します。


注:いくつかのバージョンのLexでは、 `\0'を正しく認識、 またはマッチしません。 これは、 `\0'がNUL、 つまりC文字列の終端文字だからです。 Flexでは、 NULをマッチの対象にしても問題はありませんが、 性能には若干影響します。 さらに付け加えると、 `^'演算子と`<<EOF>>'はルールの先頭にのみ置くことができます。 また、 これらと`$'、`/'は丸括弧( )の内部に置くことはできません。 このことはまた、 定義の正当性にも影響を及ぼします。 というのは、 展開される時に定義は字義どおりに丸括弧( )で囲まれるからです。2 詳細については、 DefinitionsFlex and POSIXを参照してください。


脚注

[1] 訳注:Flex 2.5では、 `-l'オプションを指定して生成されたスキャナは、 Lexの場合と同じように、 定義を展開する時に丸括弧( )で囲みません。

[2] 訳注:Flex 2.5では、 `-l'オプションを指定して生成されたスキャナは、 Lexの場合と同じように、 定義を展開する時に丸括弧( )で囲みません。