Next: , Previous: Flex, Up: Flex


8.1.1 FlexとPOSIX

Flexは、 大体のところLexおよびPOSIXの両方と互換性があります。 将来は (Flex、POSIXのどちらかが変わることによって)、 さらにPOSIXとの互換性を高めていくでしょう。 しかし、 Flex、Lex、POSIXには、 異なる部分もいくつかあります。 それを以下に示します。

排他的スタート状態
FlexとPOSIXは排他的スタート状態をサポートしていますが、 Lexはサポートしていません。
定義
LexとFlexでは定義の展開の方法が違います。 Flex(およびPOSIXのドラフト仕様)は、 定義を展開する時に丸括弧( )で囲みますが、 Lexは囲みません。1 このことは、 Flex定義では演算子‘^’、‘$’、‘/’、‘<<EOF>>’、および‘<start state>’は使うことができないということを意味しています。

このことがもたらす主要な問題の1つに、 マッチの優先順位に影響を与え、 FlexとLexの間でスキャン処理に微妙な差異が出てくるということがあります。 この問題の例については、 パターン・セクションを参照してください。


input()
FlexおよびPOSIXのドラフト仕様では、 input()は再定義可能ではありません。 Flexで入力を制御するためには、 input()を再定義する代わりに、 YY_INPUTという拡張機能を使います (これは現在のところPOSIXではサポートされていません)。 また、 Lexとは異なり、 Flexのinput()yytextの値を変更するという点に注意してください。


output()
Flexはoutput()ルーチンをサポートしていません。 ECHOの出力はyyout経由で行われます。 このyyoutのデフォルトはstdoutです。 これを使うようにoutput()を書くことも可能ですが、 現在のPOSIXのドラフト仕様は、 output()が正確には何をすべきなのかを示していません。


Ratforスキャナ
Flex、POSIXのどちらも、 LexのRatfor2スキャナ・オプション(%r)をサポートしていません。


yylineno
これは、 FlexやPOSIXには存在しない、 ドキュメント化されていないLexの機能です。3 しかし、 Flexで行数をカウントする機能を実装するのは難しくありません。 定義中に行数カウント機能を組み込む方法の例については、 See Miscellaneousを参照してください。


yywrap()
現在のところyywrap()はマクロです。 POSIXのドラフト仕様では、 これは関数であるべきとされていますので、 おそらく将来は変更されることになるでしょう。4


unput()
現在のところunput()yytextyylengの値を破壊しますが、 次のトークンがマッチされるまでは、 これは不当です。 LexとPOSIXでは、 yytextyylengunput()の影響を受けません。5
数値範囲
POSIX によると、 ‘abc{1,3}’は 「abの後ろに1個、2個、または3個のcが続くもの」 にマッチすべきとなっています。 Flexはこのとおりに動きますが、 Lexはこれを 「1個、2個、または3個のabc」 と解釈します。


yytext
Flexにおいてyytextの正しい定義は‘extern char *yytext’ですが、 Lexでは‘extern char yytext[]’です。6 配列によるアクセス方法は、 性能にかなりの影響を及ぼすので、 Flexでは‘extern char *yytext’を使い続けるでしょう。

最新のPOSIXドラフト仕様は、 ‘%array’と‘%pointer’を導入することによって、 両方の方法をサポートしています。 これは、 FlexとLexのいずれにもまだ組み込まれていません。7

テーブル・サイズ
Lexにはテーブル・サイズ宣言子(%p%a等)がありますが、 Flexでは必要ありません。 互換性のために認識はされますが、 無視されるだけです。
FLEX_SCANNER
スキャナがFlexとLexのどちらにより生成されたかによって、 コードをインクルードしたりしなかったりすることができるように、 FLEX_SCANNER#defineによって定義されています。
アクション
Flexでは、 大括弧の対{...}を使うことなく、 単一行において複数の文を置くことができます。 これに対してLexは、 そのような行を単一文に切り詰めてしまいます。
コメント
Flexではコメントを‘#’で始めることができますが、 LexとPOSIXではできません。 ただし、 この形式のコメントを使うことはお勧めできません。


yyterminate()yyrestart()<<EOF>>YY_DECL#line 指示子
これらはいずれもLexではサポートされていませんし、 POSIXにおいて明示的に定義されてもいません。 #line指示子の説明に関しては、 See Flex コマンドライン・オプションの要約

Footnotes

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

[2] 訳注:Rational Fortran

[3] 訳注:Flex 2.5では、 Flex起動時に‘-l’オプションを指定するか、 スキャナ定義ファイルの中に‘%option yylineno’を指定することによって、 変数yylinenoを利用することができます。

[4] 訳注:Flex 2.5では、 ‘%option noyywrap’が指定されない限り、 yywrap()は関数です。

[5] 訳注:Flex 2.5では、 ‘%array’を指定すれば、 unput()yytextの内容を破壊しません。

[6] 訳注:Flex 2.5では、 ‘%pointer’と‘%array’により、 yytextの型を選択できるようになりました。 デフォルトは‘%pointer’です。

[7] 訳注:Flex 2.5は、 ‘%pointer’と‘%array’をサポートしています。