1

次の Java コードを使用して、ANTLR で生成されたパーサーをインスタンス化します。

package foo;    
public class Test1 {
public static void main(String[] args) throws RecognitionException {
       CharStream stream = new ANTLRStringStream("foo ");
       BugLexer lexer = new BugLexer(stream);
       CommonTokenStream tokenStream = new CommonTokenStream(lexer);
       BugParser parser = new BugParser(tokenStream);
       parser.specification();
    }
}

私の文法:

grammar Bug;
options {
  language = Java;
}
@header {
  package foo;
}
@lexer::header {
  package foo;
}
specification : 
   'foo' EOF 
;  
WS 
   : (' ' | '\t' | '\n' | '\r')+ {$channel = HIDDEN;} 
;
SCOLON
   : (~ ';')+
;

そして、私が得るエラー:
line 1:0 mismatched input 'foo ' expected 'foo'
入力のスペースが無視されることを期待しますが、そうではありません.どういうわけか間違っていますが、表示されません... 注: SCOLON のルールを削除すると、入力のバグはなくなります。

4

1 に答える 1

2

ANTLR のレクサーは、トークンごとに可能な限り一致を試みます。そのため、 - andトークンとしてではなく"foo "、単一のSCOLONトークンとしてトークン化されています。'foo'WS

SCOLONあなたのルールに注意してください:

SCOLON
 : (~ ';')+
 ;

は、その名前から 1 つのセミコロンのみに一致することを示唆していますが、実際には、セミコロン以外の 1 つ以上の文字に一致します。おそらく、代わりにこれであるべきでした:

SCOLON
 : ';'
 ;

?

編集

ハインリヒ・オディは次のように書いています。

どういうわけか、トークン ANTLR が入力を一致させようとする優先順位 (宣言の順序によって与えられる) があると思いました。ご返信ありがとうございます。

その通りです。2 つ (またはそれ以上) のルールが同じ数の文字に一致する場合は常に、最初に定義されたルールが「優先」されます。ただし、最後に定義されたルールが最も多くの文字と一致する場合、そのルールが「勝ち」ます。

于 2012-06-10T18:13:56.863 に答える