2

このWeb ページでは、lex プログラムに「多数の予約語がある場合、単純に lex を文字列に一致させ、それが変数か予約語かを独自のコードで判断する方が効率的である」ことを示唆しています。

私の質問は次のとおりです。より効率的な場所と理由は? レクサーのコンパイルが高速であることを意味する場合、レクサーを使用して入力を解析するプログラムから 1 つのステップが削除されるため、私はそれについてあまり気にしません。

lex はあなたの説明を使用して、一度に 1 文字ずつ処理するステート マシンを構築しているようです。ステート マシンのサイズを大きくすると、識別子に 1 つのルールを使用して複数の文字列比較を行うよりも、必然的に遅くなるというのは論理的ではないように思われます。

さらに、これが最適化として理にかなっている論理的な理由があることが判明した場合、多数の予約語と見なされるのは何ですか? さまざまなことに約 30 の他のルールと比較して、約 20 のルールがあります。それは多数の予約語と見なされますか? 他のシンボルのいくつかに同じ戦略を使用する必要がありますか?

結果をグーグルで検索しようとしましたが、見つけた関連記事だけが、この戦略がよく知られているかのように説明されていましたが、理由はありませんでした。

関連する場合は、flex 2.5.35 を使用しています。

編集:これは、複数の長いリテラル文字列の照合を要求されたときに、 lexが非効率的なスキャナーを生成すると主張する別のリファレンスです。また、理由も示しません。

4

1 に答える 1

3

flex のマニュアルによると、「スキャナーの速度は、ルールの数や ... '*' や '|' などの演算子に関するルールの複雑さとは無関係です。」

主なパフォーマンスの低下は、バックトラッキングによるものです。これは、(特に)問題のあるトークンで「始まる」トークンに一致するキャッチオール ルールを使用することで回避できます。たとえば、[a-zA-Z_] で構成される予約語のリストと、[a-zA-Z_][a-zA-Z_0-9]* の形式の識別子を照合するためのルールがある場合、一致する識別子のルールは、予約語の名前で始まるすべての識別子をキャッチし、バックアップして再度一致を試行する必要はありません。

faqによると、flex は「すべてのマッチングを同時に並行して行う」決定論的有限オートマトンを生成します。この結果、上で述べたように、スキャナーの速度はルールの数に依存しません。一方、文字列比較はルールの数に比例します。

その結果、予約語ルールは、実際にはルックアップ テーブルよりもかなり高速になるはずです。

于 2012-09-30T16:13:10.847 に答える