2010-03-15 49 views
8

在第10.4节中,如果您想要在第一个解析错误时退出,则定义ANTLR引用会告诉您覆盖不匹配()& recoverFromMismatchedSet()。但是,至少在ANTLR 3.2中,似乎没有mismatch()方法,并且recoverFromMismatchedSet()文档说它是“目前未使用”。所以看起来这本书发表后事情已经发生了变化。如何让ANTLR 3.2在第一次出错时退出?

我该怎么做,而是退出ANTLR 3.2中的第一个解析错误?

回答

13

我把这个问题贴出来,Andrew Haritonkin回答。巴特K是一半的权利;您需要覆盖recoverFromMismatchedSet(),还需要recoverFromMismatchedToken()。

如果你也希望词法分析器在第一个错误退出,有一个wiki页面,说明要做什么:

http://www.antlr.org/wiki/pages/viewpage.action?pageId=5341217

简单地说,它指出:

  1. 如果你想抛出RecognitionException(或任何继承Exception的东西),那么你必须做鬼鬼祟祟的Java技巧,因为相关的方法没有声明任何异常
  2. 如果可以抛出RuntimeEx ception或Error,那么你可以重写nextToken()来抛出异常,而不是调用recoverError(),或者你可以覆盖recoverError()。抛出异常。

下面是一个例子语法在第一词法分析器或错误退出:

grammar Test; 

@parser::members { 

    public static void main(String[] args) throws Exception { 
    String text = args[0]; 
    ANTLRStringStream in = new ANTLRStringStream(text); 
    TestLexer lexer = new TestLexer(in); 
    CommonTokenStream tokens = new CommonTokenStream(lexer); 
    System.out.println(new TestParser(tokens).mainRule()); 
    } 

    @Override 
    protected Object recoverFromMismatchedToken(IntStream input, int ttype, BitSet follow) throws RecognitionException { 
    throw new MismatchedTokenException(ttype, input); 
    } 

    @Override 
    public Object recoverFromMismatchedSet(IntStream input, RecognitionException e, BitSet follow) throws RecognitionException { 
    throw e; 
    } 

} 

@rulecatch { 
    catch (RecognitionException e) { 
     throw e; 
    } 
} 

@lexer::members { 
    @Override 
    public void reportError(RecognitionException e) { 
     throw new RuntimeException(e); 
    } 

}  

mainRule returns [List<String> words] 
    @init{$words = new ArrayList<String>();} 
    : w=Atom {$words.add($w.text);} (',' w=Atom {$words.add($w.text);})* EOF 
    ; 


Atom: '0' | '1'; 

WS : ('\t' | ' ' | '\r' | '\n'| '\u000C')+ { $channel = HIDDEN; } ; 

输出示例:

C:\Users\dan\workspace\antlrtest>java -cp .;antlr-3.2.jar TestParser "1,0" 
[1, 0] 

C:\Users\dan\workspace\antlrtest>java -cp .;antlr-3.2.jar TestParser "1,,0" 
Exception in thread "main" MismatchedTokenException(6!=4) 
     at TestParser.recoverFromMismatchedToken(TestParser.java:45) 
     at org.antlr.runtime.BaseRecognizer.match(BaseRecognizer.java:115) 
     at TestParser.mainRule(TestParser.java:86) 
     at TestParser.main(TestParser.java:40) 

C:\Users\dan\workspace\antlrtest>java -cp .;antlr-3.2.jar TestParser "1,+0" 
Exception in thread "main" java.lang.RuntimeException: NoViableAltException('[email protected][])                 
     at TestLexer.reportError(TestLexer.java:16)       
     at org.antlr.runtime.Lexer.nextToken(Lexer.java:94)     
     at org.antlr.runtime.CommonTokenStream.fillBuffer(CommonTokenStream.java:119)        at org.antlr.runtime.CommonTokenStream.LT(CommonTokenStream.java:238) 
     at org.antlr.runtime.Parser.getCurrentInputSymbol(Parser.java:54)  
     at org.antlr.runtime.BaseRecognizer.match(BaseRecognizer.java:104)  
     at TestParser.mainRule(TestParser.java:68)        
     at TestParser.main(TestParser.java:40)         
Caused by: NoViableAltException('+'@[])          
     at TestLexer.mTokens(TestLexer.java:165)        
     at org.antlr.runtime.Lexer.nextToken(Lexer.java:84) 
     ... 6 more    
+0

感谢跟进丹! – 2010-03-16 06:39:38