• ANTLR从接触到搭建完毕


    antlr4官网:http://www.antlr.org

    antlr3官网:http://www.antlr3.org

    刚刚成功实现从java程序中调用antlr生成的语法文件。特此记录下。

    首先需要一个php的文法文件:

    https://code.google.com/p/phpparser

    发现这个Php.g不能使用antlr v4编译,下载v3的antlrworks,发现一调试一堆错误,很多类似

    [20:04:04] E:\output\PhpParser.java:10655: 错误: 需要<标识符>
    [20:04:04] public final void synpred23_Php_fragment() throws {

    的错误,不明原因。

    那就不要IDE了,直接下载

    http://www.antlr3.org/download.html   ->   Complete ANTLR 3.5 Java binaries jar

    里面已经包括了java的runtime。(如果使用其他语言还需要下载那个语言的runtime)

    python:(需先下载python的runtime,然后安装他,注意python的版本得根据runtime的版本,antlr_python_runtime-3.1.3这个只能支持python2.4 2.5啊。)

    http://www.antlr.org/wiki/display/ANTLR3/Antlr3PythonTarget

    支持的python版本太低了,新版antlr4里面runtime又只有java的,那就用java把。


    下面是一个简单例子的完整步骤。

    1. 下载 antlr-3.5-complete.jar

    2. 放在随便一个目录,比如D:/antlr/

    3. 添加环境变量classpath。在后面追加  D:\antlr\antlr-3.5-complete.jar;

    4. 命令行输入 java org.antlr.Tool ,会打印出参数列表,表示antlr的命令可用了。

    5. 新建一个目录,新建一个文件命名为:E.g    内容为:

    grammar E;
     
    options{ 
        output=AST;
    } 
    program : statement + ; 
    statement: (expression | VAR '=' expression) ';' ; 
    expression : (multExpr (('+' |'-' ) multExpr)*) | STRING; 
    multExpr : atom ('*' atom)*; 
    atom : INT | '(' expression ')'; 
    VAR : ('a'..'z' |'A'..'Z' )+ ; 
    INT : '0'..'9' + ; 
    STRING : '"' (('A'..'Z' | 'a'..'z' | ' ') +) '"' ; 
    WS : (' ' |'\t' |'\n' |'\r' )+ {skip();} ;

    这是一个识别算术式子和字符串的文法,下面用antrl生成词法语法分析的文件。

    6. 进入到该文件的目录,命令行输入  java org.antlr.Tool E.g ,这时会生成三个文件 E.tokens  ELexer.java  EParser.java.

    7. 接下来需要对生成的java代码编译运行,首先需要一个主函数,在该目录新建一个文件命名为 run.java。输入内容:

    import org.antlr.runtime.*; 
    import org.antlr.runtime.tree.*; 
    public class run {
        public static void main(String[] args) throws Exception  {
            ANTLRInputStream input = new ANTLRInputStream(System.in);
            ELexer lexer = new ELexer(input);
            CommonTokenStream tokens = new CommonTokenStream(lexer);
            EParser parser = new EParser(tokens);
            EParser.program_return r = parser.program();
            System.out.println(((BaseTree)r.getTree()).toStringTree());  }
    } 

    这里的parser.program()中program()是我们文法的起点,就是第一条规则的名字,如果不是这个则需要修改,同时.program_return中下划线前面的部分跟随一起修改。

    8. 编译所有的.java文件。命令行输入: javac *.java ,生成class文件后,执行run。输入 java run。此时需要输入参数,输入

    2+4*5;

    str="hello";

    ^Z

    ^Z是按Ctrl+Z产生的,表示输入结束。回车后发现结果

    2 + 4 * 5 ; str = "hello";

    表示运行成功了,至于为什么打印这个结果是因为run.java里使用了toStringTree(),更多的API可见

    http://www.antlr3.org/api/

    9. 学习API,更详细的分析生成的抽象语法树。

    10. over.

    补充:Ast树的简单遍历操作

    //转为CommonTree格式,CommonTree类提供一些操作树的方法供我们使用
            CommonTree root = (CommonTree)r.getTree();
            
            //输出树的string格式
            System.out.println(root.toStringTree());
            //获取节点root的子节点个数
            System.out.println(root.getChildCount());
            //获取root的第1个(从0开始)孩子
            CommonTree se = (CommonTree) root.getChild(1);
            //获取root的第1个(从0开始)孩子的第2个孩子
            CommonTree th = (CommonTree) se.getChild(2);
            //获取节点 th 的父节点
            System.out.println(th.getParent());
            //判断节点 root 是不是根节点
            System.out.println(root.isNil());
            /*这里只写出几个简单的方法供参考,更多的的请参考
            http://www.antlr3.org/api/Java/index.html
            查看 Class CommonTree 和 Class BaseTree 的部分*/
  • 相关阅读:
    gulp-rev:项目部署缓存解决方案----gulp系列(六)
    nodemailer实现node发送邮件
    angular项目总结——angular + browserify + gulp + bower + less 架构分享
    作为面试官之后的一些体会
    前端乱炖,总结一些细节点
    webapp,liveapp: 流式布局和rem布局
    canvas剪裁图片并上传,前端一步到位,无需用到后端
    (高德地图)marker定位 bug 解决总结
    gulp-clean----gulp系列(五)
    APUE-文件和目录(一)
  • 原文地址:https://www.cnblogs.com/leonbond/p/2960354.html
Copyright © 2020-2023  润新知