2017-07-04 114 views
2

我想用antlr4解析數字(雙精度和整數),但未能成功。希望可以有人幫幫我。Antlr4解析數失敗

我的測試代碼是:

public class TestAntlr4 { 

    @Test 
    public void test() throws IOException { 
     String input = "30"; 

     CharStream inputCharStream = new ANTLRInputStream(new StringReader(input)); 
     // create a lexer that feeds off of input CharStream 
     TokenSource tokenSource = new GqlLexer(inputCharStream); 
     // create a buffer of tokens pulled from the lexer 
     TokenStream inputTokenStream = new CommonTokenStream(tokenSource); 

     // create a parser that feeds off the tokens buffer 
     TestAntlr4Parser parser = new TestAntlr4Parser(inputTokenStream); 

     parser.removeErrorListeners(); // remove ConsoleErrorListener 
     parser.addErrorListener(new VerboseListener()); 

     parser.getInterpreter().setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION); 

     NumberContext context = parser.number(); 

     System.out.println(context.toString()); 
    } 
} 

我antlr4語法是:

grammar TestAntlr4 ; 


number 
    : INT_NUMBER 
    | DOUBLE_NUMBER ; 

DOUBLE_NUMBER 
    : ('+'|'-')? INTEGER '.' INTEGER? ; 

INT_NUMBER 
    : ('+'|'-')? INTEGER ; 

WS 
    : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines 

fragment INTEGER 
    : '0' 
    | '1'..'9' ('0'..'9')* ; 

fragment DIGIT 
    : [0-9] ; 

結果是:

rule stack: [number] 
line 1:0 at [@0,0:1='30',<31>,1:0]: mismatched input '30' expecting {DOUBLE_NUMBER, INT_NUMBER} 
[] 

誰能告訴我什麼是錯的呢?

+0

查看下面更新的答案。 – TomServo

回答

1

語法似乎沒問題。 LEXES並解析正常,我用輸入 「30」:

[@0,0:1='30',<INT_NUMBER>,1:0] 
[@1,2:1='<EOF>',<EOF>,1:2] 

具有雙重也試過:

[@0,0:6='30.3343',<DOUBLE_NUMBER>,1:0] 
[@1,7:6='<EOF>',<EOF>,1:7] 

解析就好了。

現在,在我的環境中,我使用C#目標,所以我的代碼與您的代碼有點不同。

我的(C#)使用訪問者模式代碼:

   AntlrInputStream inputStream = new AntlrInputStream(stream); 
       Grammar1Lexer lexer = new Grammar1Lexer(inputStream); 
       CommonTokenStream tokenStream = new CommonTokenStream(lexer); 
       Grammar1Parser parser = new Grammar1Parser(tokenStream); 
       IParseTree tree = parser.number(); 
       Grammar1Visitor visitor = new Grammar1Visitor(); 
       visitor.Visit(tree); 

編譯和工作得很好。

UPDATE:

我注意到,你的詞法分析器和解析器被命名爲不同的,你可以有一個簡單的複製/粘貼錯誤?通常當你生成這些類時,所有的命名都是基於你的語法名稱統一命名的。

+0

感謝您的快速回復,並且您真的解決了我的問題。其實我在我的真實項目中遇到了antrl4問題,並且我簡化了測試的語法,但是複製和修改單元測試代碼時出現錯誤。很好的觀察!當我更正Lexer時它工作:> TokenSource tokenSource = new TestAntlr4Lexer(inputCharStream); – arganzheng