Antlr生成java 运行环境

下面录入文法文件,运行ANTLRWorks点击“File– New”菜单新建文法文件,在新文件中将前面的文法录入。(我的网站中有本书所有示例源代码,但我建议您还是手工录入一遍。这样您会有更好的学习效果。)录入文法后点击“File – Save” 菜单文件名为“E.g”。然后点击“Generate–GenerateCode”,如果ANTLRWorks提示“The grammar has been successfully generatedin path…”说明ANTLRWorks成功生成了语法分析器的代码。会在“E.g”的当前目录中生成“ELexer.java”、“EParser.java”、“E.tokens”和“E__.g”四个文件,其中有两个java源文件。“ELexer.java”为词法分析部分的代码,“EParser.java”为语法分析部分的代码。那么为什么会生成java代码呢?ANTLR在不指定目标语言的情况下默认是java语言。我们也可以在文法文件中加入options项指定目标语言。

grammarE;

options{ output=AST; language=Java; }

program: statement + ;

……

生成了代码后,我们来编译运行语法分析器。刚才生成的是java代码,所以先来看看java如何编译运行。首先要有一个执行程序的main方法,这个类如下:

import org.antlr.runtime.*;

import org.antlr.runtime.tree.*;

publicclass run

{

       public static void main(String[] args)throws Exception

       {

              ANTLRInputStream input = new ANTLRInputStream(System.in);

              ELexerlexer = new ELexer(input);

              CommonTokenStreamtokens = new CommonTokenStream(lexer);

              EParserparser = new EParser(tokens);

              EParser.program_returnr = parser.program();

              System.out.println(((BaseTree)r.getTree()).toStringTree());

       }

}

把这段代码存入run.java文件中,main方法功能是从命令行接收输入的表达式,通过词法分析和语法分析两个步骤来获得这个表达式的语法树,并以字符串的形式输出语法树的内容。

ANTLRInputStreaminput = new ANTLRInputStream(System.in);

ELexer lexer = new ELexer(input);

CommonTokenStream tokens = newCommonTokenStream(lexer);

词法分析步骤是从命令行接收输入的表达式,通过ANTLR内部ANTLRInputStream类,生成一个ANTLRInputStream类的实例input,再将input传给ELexer类。ELexer类是词法分析类,把input中的输入内容进行词法分析,词法分析后会产生词号流(token stream)交给语法分析类,为语法分析提拱前提。

EParserparser = new EParser(tokens);

EParser.program_return r =parser.program();//此处进行了语法分析

System.out.println(((BaseTree)r.getTree()).toStringTree());

语法分析步骤是根据词法分析产生的词号流生成语法分析类的实例parser。然后调用parser的方法program()。这个方法名和我们文法中的第一条规则program : statement + ;的名字是一致的,这说明我们要用整个文法进行分析,program是文法的启点。调用program()方法后就进行了语法分析,program()方法返回语法分析的信息其中包括语法树。r.getTree()可以返回语法树,getTree()返回的是Object类型所以这里做一个类型转换(BaseTree)r.getTree()并调用其toStringTree()方法获得语法树的字符串形式输出。

到现在完成了源代码的录入工作,接下来编译所有的代码。编译的命令行字符串为:

javac -classpath .;.....\antlr-3.0.1\lib\antlr-3.0.1.jar*.java

run.java中的import org.antlr.runtime.*;importorg.antlr.runtime.tree.*;所引用的类包含在antlr-3.0.1.jar中,解压我们之前下载的antlr-3.0.1.tar.gz文件,在其中的lib目录中可以找到antlr-3.0.1.jar。编译字符串中的-classpath参数中给出.....\antlr-3.0.1\lib\antlr-3.0.1.jar的实现路径。运行程序的命令行字符串与编译字符串相似:

java -classpath .;.....\antlr-3.0.1\lib\antlr-3.0.1.jar  run

好的我们来执行这两个字符串来编译并执行程序,执行程序后命令行光标会等待输入,把之前准备分析的两个表达式输入,然后按Ctrl+Z(Windows系统Ctrl+Z,UNIX系统Ctrl+D)表示输入结束,然后回车。

23+4*(5+1);

str="hello world";

^Z

23 + 4 * ( 5 + 1 ) ; str = "hello world" ;

 

 
 

 

 

 


程序输出23 + 4 * ( 5 + 1 ) ; str = "helloworld" ;这表示程序执行成功了。我们的语法分析器已经正确的解析了这两个表达式。您可以试着用不规则的格式输入两个表达式会得到相同的输出,因为已经正确分析了表达式的语法,所以输出格式化的字符串对我们的分析器来说是很简单的事情了。

        23    +4*(        5+   1

);str

"  hello world  "

;

^Z

23 + 4 * ( 5 + 1 ) ; str = "  hello world  " ;

 

 
 

 

 

 

 

你可能感兴趣的:(java,exception,Stream,input,语言,import)