みんなへー
ドメイン固有言語の解析に使用されるレクサーを構築しようとしています。予約済みトークン (フラグメント RESERVED) とエスケープ文字のセットがあります。レクサーは、エスケープされていない予約済みトークンが表示されるたびに分割する必要があります。
簡単な例:
SEP: ';';
AND: '&&';
fragment ESCAPE: '/';
fragment RESERVED: SEP | AND | ESCAPE;
SINGLETOKEN : (~(RESERVED) | (ESCAPE RESERVED))+;
問題:
RESERVED に 1 文字のトークンしか含まれていない限り、これは正常に機能します。否定演算 ~ は、単一の文字に対してのみ機能します。
残念ながら、文字列トークンでも動作する必要があります。したがって、1 文字を超えるトークン (例の AND を参照)。そうする簡単な方法はありますか?これはさまざまな言語にコンパイルする必要があり、別のコピーを維持したくないため、Java または C コードをインライン化せずに問題を解決する必要があります。
誰かが私を助けてくれることを願っています
スクリプト全体からのサンプル入力
作成;false;false;1.key = bla; トリグ;true;false;(1.key1 ~ .*thisIsRegex || 2.oldKey1 €) && (1.bla=2.blub || 1.blub=bla);
レクサーの後、これは次のようになります。トークン区切りの空白は重要ではありません:|create|;|false|;|false|;|1.|key| = |ブラ|;| trig|;|true|;|false|;|(|1.|key1| ~| .*thisIsRegex| || |2.|oldKey1| €|)| && |(|1.|bla|=|2.|ブラブ| || |1.|ブラブ|=|ブラ|)|;|
スクリプト全体はhttp://pastebin.com/Cz520VW4にあります (このリンクは 1 か月で期限切れになることに注意してください)。現在、正規表現の部分はまだ機能しません。
可能だが恐ろしい解決策
考えられる解決策を見つけましたが、それは本当にハックであり、スクリプトがエラーを起こしやすくなります。だから私はもっときれいなものを見つけたいと思っています。
私が現在行っているのは、否定 (~RESERVED) を手で書いていることです。
SEP: ';';
AND: '&&';
fragment ESCAPE: '/';
fragment RESERVED: SEP | AND | ESCAPE;
NOT_RESERVED:
: '&' ~('&' | SEP | ESCAPE)
// any two chars starting with '&' followed by a character other then a reserve character
| ~('&' | SEP | ESCAPE) ~(SEP | ESCAPE)
// other than reserved character followed by '&' followed by any char
;
SINGELTON : (NOT_RESERVED | (ESCAPE RESERVED))+;
実際のスクリプトには 5 つ以上の複数文字トークンがあり、後で 2 文字以上になる可能性があるため、この方法で問題を解決すると非常に複雑になります。