3

みんなへー

ドメイン固有言語の解析に使用されるレクサーを構築しようとしています。予約済みトークン (フラグメント 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 文字以上になる可能性があるため、この方法で問題を解決すると非常に複雑になります。

4

1 に答える 1