1

現在、レクサーとパーサーがどのように機能するかを学んでおり、ステート マシンについて次の質問があります。たとえば、次のルールに従ってテキストを色付けする必要があります。このルールでは、単純な状態遷移表は次のようになります。

current event next  action
IDLE    $     COLOR -
COLOR   any   -     OnColor()
COLOR   \n    IDLE  -

これにより、「$」と行末の間にあるすべての文字に対して OnColor() アクションが呼び出されるため、色付けできます。もちろん、正規表現から同じものを自動的に生成することもできますが、魔法を大量に使用する前に、それがどのように機能するかを知りたいです:)。次に問題が発生します:ルールがある場合:(ドルで終わるテキスト行に色を付けたい場合、状態遷移表はあまり明確ではありません:

current      event next             action
IDLE         any   -                -
IDLE         $     DOUND_DOLLAR     -
FOUND_DOLLAR \n    IDLE             OnDollar()
FOUND_DOLLAR any   IDLE             -

行末に「$」記号が見つかった場合に OnDollar() を呼び出すようにステート マシンに教えることができますが、ドル記号が出現する前のテキストを色付けするにはどうすればよいでしょうか? そのような問題を解決するための一般的なパターンは何ですか? もちろん、正規表現で 1 行になりますが、そのようなパーサーがステート マシンを介してどのように実装できるか、またそれが可能であるかを知りたいと思っています。

4

3 に答える 3

1

一度に 1 つの文字に色を付けるように制約されている場合 (つまり、バッファリング、先読み、再色付け、またはマーキング機能がない場合)、それは不可能です。

それ以外の場合は、そのような機能があれば実行できます。テクニックは、利用可能なものに依存します。

  • 色の変更 - n 文字の色を元に戻すアクションがあります。明らかに、これは簡単な解決策です。

  • バッファリング/マーキング - 文字を通過させるのではなく、文字をバッファの最後に配置する/ソースに名前付きマークを設定するアクションがあります。その後、後で何をすべきかがわかったときに、何らかの方法でバッファーをコミットするアクション、または名前付きマークからフラッシュするアクションを用意します。ただし、これで複数のキャラクターの色を変更すると、やや複雑になります。

  • 先読み - 投機的な遷移を行います。つまり、 DFAの代わりにNFAを使用します。

于 2009-05-08T10:15:37.780 に答える
0

"Purple Dragon Book" (原文のまま) を読むと、最新のコンパイラとインタプリタは積極的に "先読み" バッファを使用して最近のテキストを蓄積しているように見えます。そのため、正確な字句タイプを取得するために、次のシンボルと前のシンボルを簡単に確認できます。

したがって、私の例では、 event() は、蓄積される可能性のある語彙のタイプを決定するために、前後のシンボルを調べる必要があります。

于 2009-05-10T12:46:02.003 に答える
0

ほとんどのカラーライザーは常に、行全体 (ほとんどの場合、これで十分です) と複数行のコメントの「リーク」フラグなど、より大きなブロックで動作します。このような APIについては、 Qt Syntax Highlighterの例を参照してください。

于 2009-05-08T10:32:51.233 に答える