1

私は Flex/Bison を約 6 時間使用してきましたが、解決できない最初の問題は次のとおりです。

次のファイルがあります...

 state state1: {
     1-3: 255
     4: 255
 }

...これを、cat と | を使用して flex/bison プログラムに渡します。flex ファイルには次の行が含まれています。

\bstate\b  { return STATE; }

そして、これをさらに下に:

.*         { fprintf(stderr, "Lexer error on line %d: \"%s\"\n", linenum, yytext); exit(-1); }

ファイル内で \bstate\b が一致するはずだと考えるべきですが、そうではありません。代わりに、次の出力が得られます。

"exer error on line 1: "state state1: {

これはいくつかの点で奇妙です。まず、Lexer シームの L が " に置き換えられましたが、さらに重要なことに、状態が一致しませんでした。

もちろん、\bstate\b は .* の前にあり、右側のセクションにあります。

助けてくれてありがとう、ジャン

4

1 に答える 1

4

(F) Lex は、一致する入力を検索しません。現在の入力位置ですべてのパターンを試行し、最も多くのテキストに一致するものを選択するか、複数のパターンが同じ量のテキストに一致する場合は最も古いものを選択します。次の lex マッチは、前のマッチが終了した場所から開始されます。

.*行の残りの部分に一致します。\bstate\b7 文字のみに一致します。それ.*で勝つでしょう。しかし\bstate\b、これは lex であり、<お気に入りの正規表現構文をここに挿入> ではなく\b、C プログラムのようにバックスペースを意味するため、実際には一致しません。

文字 L が引用符で上書きされている理由は、おそらく入力ファイルが Windows で作成され、行末に \r\n があるためです。は、キャリッジ リターンである.*を含む まで一致します。\rしたがって、 printf を実行する"%s"\nと、 %s を置き換える文字列の最後の文字は改行になり、カーソルが現在の行の最初の場所に移動します。その時点までは L が含まれていました。次に、" が L の上に印刷され、最後に改行文字が印刷され、新しい行が開始されます。

単語境界アサーションに相当する Lex はありません\bが、それが問題になることはめったにありません。事実上すべてのプログラミング言語の字句スキャナーは、予約語が識別子のパターンにも一致するという問題に対処する必要があります。ただし、最長一致ルールと最初の一致ルールを組み合わせることで、これを簡単に行うことができます。簡単に言えば、常に予約語パターンを最初に置きます。例えば:

do              { return DO; }
double          { return DOUBLE; }
if              { return IF; }
/* ... */
[a-z][a-z0-9]*  { return ID; }

上記の例では、長いので、並べる順序は問題ではdoありdoubleませんが、doubleきちんと整理するために、予約語をアルファベット順に並べるべきだといつも感じています。ただし、ID パターンはすべての予約語にも一致するため、最後に配置することが重要です。

のような予約語で始まる識別子を字句解析するとどうなるかを考えてみましょうdog。この場合、DO パターンと ID パターンの両方が一致しますが、ID の一致の方が長いため、遅くても勝ちます。

于 2012-10-11T05:47:30.127 に答える