4

flex のデフォルト アクションをカスタマイズするにはどうすればよいですか。<*> のようなものを見つけましたが、実行すると「フレックス スキャナーが詰まっています」と表示されますか? また、 . rule はルールを追加するだけなので、どちらも機能しません。私が欲しいのは

comment               "/*"[^"*/"]*"*/"

%%
{comment}             return 1;
{default}             return 0; 
<<EOF>>               return -1;

最長一致の動作を最初に一致するように変更することは可能ですか? もしそうなら、私はこのようなことをします

default               (.|\n)*

しかし、これはほとんどの場合、より長い一致を与えるため、コメント ルールを非表示にします。

編集

マニュアルで {-} 演算子を見つけましたが、この例はマニュアルから直接「認識されていないルール」を示しています。

[ac]{-}[bz]

4

3 に答える 3

8

フレックス デフォルト ルールは、単一の文字に一致し、それを標準出力に出力します。そのアクションが必要ない場合は、1 つの文字に一致し、別のことを行う明示的なルールを記述します。

パターン(.|\n)*は入力ファイル全体を 1 つのトークンとして照合するため、これは非常に悪い考えです。デフォルトは長い一致である必要があると考えていますが、実際にはできるだけ短くする必要があります (ただし、空ではありません)。

デフォルト ルールの目的は、入力言語のどのトークンにも一致しない場合に何かを行うことです。言語をトークン化するために lex を使用する場合、このような状況はほとんど常に誤りです。これは、入力がその言語の有効なトークンの先頭ではない文字で始まることを意味するためです。

したがって、「任意の文字をキャッチ」ルールは、エラー回復の形式としてコーディングされます。アイデアは、悪い文字 (1 つだけ) を破棄し、その後の文字からトークン化を試みることです。これは推測にすぎませんが、既知の情報、つまり入力に 1 つの不適切な文字があることに基づいているため、適切な推測です。

リカバリ ルールが間違っている可能性があります。たとえば、言語のトークンが で始まらず@、プログラマーが文字列リテラル を書きたいとします"@abc"。ただ、彼女は冒頭を忘れて"書い@abc"た。正しい修正は"、 を破棄するのではなく、欠落している を挿入すること@です。しかし、そのためには、レクサーでより巧妙な一連のルールが必要になります。

とにかく、通常、悪い文字を破棄する場合、この場合は「42 行 3 列目の無効な文字 '~` をスキップします」のようなエラー メッセージを発行します。

一致しない文字を標準出力にコピーするデフォルトのルール/アクションは、テキスト フィルタリングに lex を使用する場合に役立ちます。次に、デフォルトのルールは、(正規表現の一致ではなく) 正規表現検索のセマンティクスをもたらします。アイデアは、その検索によってスキップされたすべての素材を出力しながら、レクサーのトークン認識ステート マシンの一致について入力を検索することです。

たとえば、ルールだけを含む lex 仕様は次のようになります。

 "foo" { printf("bar"); }

同等のものを実装します

 sed -e 's/foo/bar/g'
于 2012-04-22T19:30:42.717 に答える
1

ルールの補数を一致させようとする場合、代わりに手動で問題を解決しました。この場合に含まれる一致パターンは非常に単純であるため、これはうまく機能します。

于 2012-04-23T05:49:03.420 に答える
1

なぜ「。」を追加するのですか?トリックをしませんか?金額が一致しないとアクションを実行できません。一致するものがない場合、flex は何もしません。そのため、「デフォルト」ルールを追加するには、何かに一致させるだけです。

于 2012-04-22T12:42:27.663 に答える