体验Antlr3.0
国内使用过Antlr2.x系列的人有相当一部分,然而用过3.x的人不是很多,因为3系列的语法相对于2系列的也有较大改进,3系列的中文资源几乎是一片空白。
写个简单的1+1的例子来体验一下。
grammar Calc;
options{
language=CSharp2;
}
expr returns [int tvalue=0]
: a = INT PLUS b = INT
{
int aValue = int.Parse($a.text);
int bValue = int.Parse($b.text);
tvalue = aValue + bValue;
}
;
PLUS : '+' ;
INT : ('0'..'9')+ ;
编译后生成CalcLexer.cs和CalcParser.cs文件.
新建一个项目.
添加antlr.runtime.dll与Antlr3.Runtime.dll引用
在某个事件下添加如下代码:
Antlr.Runtime.ICharStream intStr = new Antlr.Runtime.ANTLRStringStream(textBox1.Text);
CalcLexer lexer = new CalcLexer(intStr);
Antlr.Runtime.CommonTokenStream tok = new CommonTokenStream(lexer);
CalcParser parser = new CalcParser(tok);
try
{
textBox3.Text= parser.expr().ToString();
}
catch
{
}
在输入1+1进行测试过程中,发现
public int expr() // throws RecognitionException [1]
{
int tvalue = 0;
IToken a = null;
IToken b = null;
try
{
// C:\\Calc.g:7:9: (a= INT PLUS b= INT )
// C:\\Calc.g:7:11: a= INT PLUS b= INT
{
a=(IToken)Match(input,INT,FOLLOW_INT_in_expr40);
Match(input,PLUS,FOLLOW_PLUS_in_expr42);
b=(IToken)Match(input,INT,FOLLOW_INT_in_expr48);
int aValue = int.Parse(((a != null) ? a.Text : null));
int bValue = int.Parse(((b != null) ? b.Text : null));
tvalue = aValue + bValue;
}
}
catch (RecognitionException re)
{
ReportError(re);
Recover(input,re);
}
finally
{
}
return tvalue;
}
里面如何执行不得而知,连这么简单的都得不到正确的结果,很让人郁闷.
于是反编译一下:
幸好发现可以重载,于是将代码拷贝到子类中,将this都去掉.再编译测试.发现竟然能够输出正确结果了.
Antlr能够支持多种语言,不知道在其他语言环境下是否有这样的问题,记录在此,希望能够相互学习和
借鉴.也请各位能够给予批评和建议.