伯约的技术家园

导航

体验Antlr3.0

     Antlr(ANother Tool for Language Recognition)是一个工具,它为我们构造自己的识别器(recognizers)、编译器(compiler)和转换器(translators)提供了一个基础。通过定义自己的语言规则,Antlr可以为我们生成相应的语言解析器,这样便可以省却了自己全手工打造的劳苦。
    国内使用过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.dllAntlr3.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;
    }

   当执行到红色标示的地方时,就会抛出一个异常.因为是调用的Antlr3.Runtime.dll中的方法.
   里面如何执行不得而知,连这么简单的都得不到正确的结果,很让人郁闷.
   于是反编译一下: 
  
    幸好发现可以重载,于是将代码拷贝到子类中,将this都去掉.再编译测试.发现竟然能够输出正确结果了.
    Antlr能够支持多种语言,不知道在其他语言环境下是否有这样的问题,记录在此,希望能够相互学习和
    借鉴.也请各位能够给予批评和建议.

posted on 2008-07-01 22:11  伯约  阅读(3986)  评论(2编辑  收藏  举报