2013-11-28 50 views
1

我想要一个简单的计算器,并在C#中使用ANTLR运行。我有一个简单的语法。问题是我的令牌流总是空出来的,我不明白为什么。我已经摘录了我认为是下面的关键代码。我错过了什么?ANTLR标记流为空 - 为什么?

SimpleCalc.g4:

grammar SimpleCalc; 

options { 
language=CSharp2; 
} 

tokens { 
    PLUS, 
    MINUS, 
    TIMES, 
    DIV 
} 

@members { 

} 

expr : term ((PLUS|MINUS) term)* ; 
term : factor ((TIMES|DIV) factor)* ; 
factor : NUMBER ; 
DIV : '/'; 
PLUS : '+'; 
TIMES: '*'; 
MINUS: '-'; 

NUMBER : (DIGIT)+ {System.Console.WriteLine("Found number"); }; 
WHITESPACE: ('\t' | ' ' | '\r' | '\n' | '\u000C')+ -> skip ; 
fragment DIGIT : '0'..'9'; 

中的方法做实际工作,或尝试:

class Program { 

    public static void Main(string[] args) { 
    Run(); 
    } 

    public static void Run() { 

    try { 
     Console.WriteLine("START"); 
     RunTestCalculator(); 
     Console.Write("DONE. Hit RETURN to exit: "); 
    } catch (Exception ex) { 
     Console.WriteLine("ERROR: " + ex); 
     Console.Write("Hit RETURN to exit: "); 
    } 
    Console.ReadLine(); 
    } 

    public static void RunTestCalculator() { 
    AntlrInputStream inputStream = new AntlrInputStream(@" 9 + 3 "); 
    SimpleCalcLexer lex = new SimpleCalcLexer(inputStream); 
    CommonTokenStream tokens = new CommonTokenStream(lex); 
    var t = tokens.Get(0); 
    Console.WriteLine("t = " + t.ToString()); 
    SimpleCalcParser parser = new SimpleCalcParser(tokens); 
    try { 
     var theExpr = parser.expr(); 
     Console.WriteLine("found expr " + theExpr.ToString()); 
    } catch (RecognitionException e) { 
     System.Console.WriteLine("EXCEPTION:"); 
     System.Console.WriteLine(e.StackTrace); 
    } 
    } 
} 

控制台输出证明了上述方法执行,但令牌不包含任何东西:

START 
ERROR: System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values. 
Parameter name: token index 0 out of range 0..-1 
    at Antlr4.Runtime.BufferedTokenStream.Get(Int32 i) 
    at AntlerTest.Program.RunTestCalculator() in c:\Users\William\Documents\Visual Studio 2012\Projects\AntlerTest\AntlerTest\Program.cs:line 32 
    at AntlerTest.Program.Run() in c:\Users\William\Documents\Visual Studio 2012\ 
Projects\AntlerTest\AntlerTest\Program.cs:line 19 
Hit RETURN to exit: 

回答

0

我所缺少的是令牌流保持为空直到expr调用。当我在expr之后移动get调用,令牌在那里:

public static void RunTestCalculator() { 
     AntlrInputStream inputStream = new AntlrInputStream(@" 9 + 3 "); 
     SimpleCalcLexer lex = new SimpleCalcLexer(inputStream); 
     CommonTokenStream tokens = new CommonTokenStream(lex); 
     SimpleCalcParser parser = new SimpleCalcParser(tokens); 
     try { 
      var theExpr = parser.expr(); 
      Console.WriteLine("found expr " + theExpr.ToString()); 
    var t = tokens.Get(0); 
    Console.WriteLine("t = " + t.ToString()); 
     } catch (RecognitionException e) { 
      System.Console.WriteLine("EXCEPTION:"); 
      System.Console.WriteLine(e.StackTrace); 
     } 
    } 

输出:

START 
Found number 
Found number 
found expr [] 
t = [@0,1:1='9',<5>,1:1] 
DONE. Hit RETURN to exit: