質問
現在、レクサーとパーサーがどのように機能するかを学習していますが、ステートマシンについて次の質問があります。たとえば、次のルールに従ってテキストを色付けする必要があります。 このルールでは、単純な状態遷移テーブルは次のようになります。
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行になりますが、このようなパーサーをステートマシン経由で実装する方法を知りたいと思っています。
解決 3
「パープルドラゴンブック」を読むと、 (原文)「先読み」を積極的に使用している最新のコンパイラとインタプリタ正確な字句タイプを取得するために、次のシンボルと前のシンボルを簡単にチェックできるように、最近のテキストをバッファリングして蓄積します。
したがって、私の例では、event()は、蓄積される可能性のある語彙の種類を決定するために、次のシンボルと前のシンボルを調べる必要があります。
他のヒント
一度に1文字を着色するように制限されている場合(つまり、バッファリング、先読み、再着色、またはマーキング機能がない場合)、それは不可能です。
それ以外の場合、そのような機能がある場合は実行できます。テクニックは利用可能なものに依存します。
-
色変更-n文字を元に戻すことができるアクションがあります。明らかに、これは簡単な解決策です。
-
バッファリング/マーキング-キャラクターを通過させるのではなく、バッファーの最後にキャラクターを配置する/ソースに名前付きマークを設定するアクションがあります。その後、後で何をすべきかを見つけたら、バッファを何らかの方法でコミットするアクション、または名前付きマークからフラッシュするアクションを実行します。ただし、これで複数の文字の色を変更すると多少複雑になります。
-
Lookahead-投機的な遷移があります。つまり、<ではなく NFA を使用しますa href = "http://en.wikipedia.org/wiki/Deterministic_finite_state_machine" rel = "nofollow noreferrer"> DFA 。
ほとんどのカラライザーは常に大きなブロックで動作します。たとえば、行全体(ほとんどの場合はこれで十分です)と「リーク」たとえば、複数行コメントのフラグ。このようなAPIの例については、 Qt構文ハイライターの例をご覧ください。