2

私は次のAntlr文法を持っています:

grammar MyGrammar;

doc :   intro planet;
intro   :   'hi';
planet  :   'world';
MLCOMMENT 
    :   '/*' ( options {greedy=false;} : . )* '*/' { $channel = HIDDEN; };
WHITESPACE : ( 
    (' ' | '\t' | '\f')+
  |
    // handle newlines
    ( '\r\n'  // DOS/Windows
      | '\r'    // Macintosh
      | '\n'    // Unix
    )
    )
 { $channel = HIDDEN; };

ANTLRWorks 1.2.3 インタープリターでは、入力hi worldとが期待どおりhi/**/worldhi /*A*/ world機能します。

ただし、動作しないはずの inputhiworld受け入れられます。どうすればhiworld失敗しますか?「こんにちは」と「世界」の間に少なくとも 1 つの空白 (またはコメント) を強制するにはどうすればよいですか?

この例では、簡略化のために MLCOMMENT と WHITESPACE のみを使用していますが、他の種類のコメントもサポートされていることに注意してください。

4

2 に答える 2

6

一般的な ID トークンを作成する必要があります。lexer は可能な限り最長のトークンを作成するため、入力 "hiworld" は "hi" または "world" 自体よりも長いため、1 つの単語として認識されます。このようなルールは次のようになります。

ID : ('a'..'z' | 'A'..'Z')+;

例として、プログラミング言語のパーサーが "do" キーワードを "double" (キーワード タイプ、"do" で始まる) または "done" (変数名) から分離する方法はまさにこれです。

于 2009-07-19T01:54:26.187 に答える
0

文字列を失敗させる 1 つの方法hiworldは、次のように、失敗することが保証されている検証セマンティック述語を使用することです。

doc:      intro planet;
failure : 'hiworld' { false }?;
intro   : 'hi';
planet  : 'world';
// rest of grammar omitted
于 2009-07-18T18:03:04.533 に答える