安装java环境,环境变量设置如下:

ANTLR 简介

  1. ANTLR—Another Tool for Language Recognition,Antlr 本身是使用 Java 开发的,它为包括Java,Python,C#在内的语言提供了一个通过语法描述来自动构造自定义语言的识别器(recognizer),编译器(parser)和解释器(translator)的框架。
  2. Antlr 使用上下文无关文法描述语言, 它允许我们定义识别字符流的词法规则和用于解释Token流的语法分析规则。然后,ANTLR将根据用户提供的语法文件自动生成相应的词法/语法分析器。用户可以利用他们将输入的文本进行编译,并转换成其他形式.

ANTLR 安装

安装有两种:一种手动使用命令行安装与执行,第二种则是借助强大的Eclipse的插件安装。 Eclipse插件安装,官网给出了很详细的教程
连接如下:
Eclipse+Antlr V4 这里就不说了。
无论那种方式,执行的过程原理都没有变。
首先说明下配置的环境:

Ubuntu 14.04 32bit
Antlr V4
jdk 1.7
  • 1
  • 2
  • 3

安装jdk

ANTLR是用Java编写的,所以在你开始之前需要先安装Java。ANTLR v4需要Java 1.6 以上版本。安装的具体过程可以参考网上教程,挺多的。这里我安装都是jdk 1.7 版本

命令行安装

  1. 下载ANTLR v4,截止到2015.6,官网最新的为antlr-4.5-complete.jar ,可以使用如下的shell命令下载:
    curl -O http://www.antlr.org/download/antlr-4.5-complete.jar
    或者直接到[][http://www.antlr.org/download.html] 处下载,
    之后,拷贝到/usr/local/lib 目录下供使用。
  2. 添加环境变量
    修改环境变量如下:直接修改gedit ~/.bashrc:找到CLASSPATH 行,直接再后面追加下面的变量, 完成保存之后, 执行source ~/.bashrc 生效。
:/usr/local/lib/antlr-4.5-complete.jar
  1. 修改快捷命令
    下面的两个命令也是最常用的,这里设定别名来方便使用。
    同样在直接修改gedit ~/.bashrc 找到alias 再后面加上下面两行就可。完成保存退出,执行source ~/。bashrc 即可
$ alias antlr4='java -Xmx500M -cp "/usr/local/lib/antlr-4.5-complete.jar:$CLASSPATH" org.antlr.v4.Tool
$ alias grun='java org.antlr.v4.runtime.misc.TestRig

样例测试

命令行测试

在我们的工作目录比如说 ~/workspace 下建立一个Hello.g4 语法文件:
内容如下: 注意文件名与 与 语法一致。

// Define a grammar called Hello
grammar Hello;
r : 'hello' ID ; // match keyword ‘hello’ followed by an identifier
ID : [a-z]+ ; // match lower-case identifiers
WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines

这个语法很简单,只识别hello 后面接小写字母组成的字符串。
然后开始编译:

$ cd workspace
$ antlr4 Hello.g4 #这一步会自动生成几个java文件,下一步编译java
$ javac Hello*.java

可以ls 一下该目录,会发现有这么几个文件

HelloBaseListener.class  HelloLexer.java      HelloParser.class
HelloBaseListener.java HelloLexer.tokens HelloParser.java
Hello.g4 HelloListener.class HelloParser$RContext.class
HelloLexer.class HelloListener.java Hello.tokens

表示已经编译完成,可以使用前面重命名的命令grun 来测试,,命令格式: grun file.g4 -r [option] 其中常用的参数有这三个:

 - tokens #打印出token流
- tree #用LISP表单打印出解析树
- gui #在对话框中可视化地展示解析树

测试如下:

$ grun Hello r -tree
hello world#输完执行命令之后, 在这里输入一个字符串
^D#由于程序会一直等待用户输入,所以这里使用 ctrl +D 结束输入
(r hell world)#输出结果

我们也可查看创建的tokens:

 grun  Hello r -tokens
hello world
^D
[@0,0:4='hello',<1>,1:0]
[@1,6:10='world',<2>,1:6]
[@2,12:11='<EOF>',<-1>,2:0]
#-------------#
[“1,6:10 = ‘world’,<2>,1:6]表明第二个token(索引从0开始),从字符位置6到10(从0开始),有文本world,是第二个标记(ID),位置是在第一行(行数从1开始),在第6个字符处(位置是从零开始计算,tabs也算作一个独立的字符)。

最后可以测试语法规则的图示形式

grun Hello r -gui
hello world
^D
  • 1
  • 2
  • 3

这时,会弹出一个窗口:

到现在可以修改.g4 文件来作其他的语法分析了。

推荐参考antlr 4权威指南, 毕竟antlr 4 在3的基础上变化不小,尽量参考新的资料。

编写简单计算器:

Expr.g4:

grammar Expr;

/** The start rule; begin parsing here. */
prog: stat+ ;

stat: ID '=' expr NEWLINE  # assign
    | NEWLINE              # blank
    ;
    
expr: leftNum op=('*'|'/') rigNum   # MulDiv
    | leftNum op=('+'|'-') rigNum   # AddSub
    | '(' expr ')'        # parens
    ;
    
leftNum: INT;
rigNum: INT;

ID : [a-zA-Z]+ ; // match identifiers
INT : [0-9]+ ; // match integers
NEWLINE:'\r'? '\n' ; // return newlines to parser
WS : [ \t]+ -> skip ; // toss out whitespac

接下来运行命令:

antlr4  -no-listener -visitor Expr.g4  (antlr4 PA.g4)

javac Expr*.java

grun Expr prog -gui

当前文件夹下有这个文件,通过继承该文件编写语义规则:

语义规则文件 ExprComplier.java

import java.util.HashMap;
import java.util.Map;

import org.antlr.v4.runtime.misc.NotNull;

//import .ExprBaseVisitor;
//import .ExprParser;

public class ExprComplier extends ExprBaseVisitor<Object> {
    
    Map<String, Double> memory = new HashMap<String, Double>();

public void getMemory() {
        for (Map.Entry<String, Double> entry : memory.entrySet()) {
              System.out.println("ID = " + entry.getKey() + ", Value = " + entry.getValue());
        }
    }
    
    @Override
    public Double visitAssign(@NotNull ExprParser.AssignContext ctx) {
        String id = ctx.ID().getText();
        Double value = (Double) visit(ctx.expr());
        memory.put(id, value);
        //System.out.println("ID is: " + id + " Value: " + value);
        return value;
        
    }
    
    @Override
    public Integer visitRigNum(@NotNull ExprParser.RigNumContext ctx) {
        int rigNum = Integer.parseInt(ctx.getText());
        return rigNum;
        
    }
    
    @Override
    public Integer visitLeftNum(@NotNull ExprParser.LeftNumContext ctx) {
        int leftNum = Integer.parseInt(ctx.getText());
        return leftNum;
        
    }
    
    
    @Override
    public Double visitParens(@NotNull ExprParser.ParensContext ctx) {
        return (Double) visit(ctx.expr());
        
    }
    
    @Override
    public Double visitAddSub(@NotNull ExprParser.AddSubContext ctx) {
        int leftNum  = visitLeftNum(ctx.leftNum());
        String op = ctx.op.getText();
        int rigNum  = visitRigNum(ctx.rigNum());
        if (op.equals("+")) {
            return (double) (leftNum + rigNum);
        }else if (op.equals("-")) {
            return (double) (leftNum - rigNum);
        }
        return 0.0;
        
    }
    
    @Override
    public Double visitMulDiv(@NotNull ExprParser.MulDivContext ctx) {
        int leftNum  = visitLeftNum(ctx.leftNum());
        String op = ctx.op.getText();
        int rigNum  = visitRigNum(ctx.rigNum());
        if (op.equals("*")) {
            return (double) (leftNum * rigNum);
        }else if (op.equals("/") && rigNum != 0) {
            return (double) (leftNum / rigNum);
        }
        return 0.0;
    }

编写测试文件  Test.java

//import ExprLexer;
//import ExprParser;

import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;

public class Test{
    public static void main(String[] args){
        String expr="Q=2+4"+"\n"+"P=2*4"+"\n"+"R=6/2"+"\n";
        ANTLRInputStream input=new ANTLRInputStream(expr);
        ExprLexer lexer=new ExprLexer(input);
        CommonTokenStream tokens=new CommonTokenStream(lexer);
        ExprParser parser =new ExprParser(tokens);
        ParseTree tree = parser.prog();

ExprComplier complier = new ExprComplier();
        complier.visit(tree);
        complier.getMemory();
    }
}

编译该文件: javac Test.java

运行该文件: java    Test

antlr安装的更多相关文章

  1. 用Java写编译器(1)- 词法和语法分析

    词法和语法分析器构建 ANTLR简介 ANTLR全称ANother Tool for Languate Recognition,是基于LL(*)算法实现的语法分析器生成器和词法分析器生成器,由旧金山大 ...

  2. 从定义到AST及其遍历方式,一文带你搞懂Antlr4

    摘要:本文将首先介绍Antlr4 grammer的定义方式,如何通过Antlr4 grammer生成对应的AST,以及Antlr4 的两种AST遍历方式:Visitor方式和Listener方式. 1 ...

  3. Fabio 安装和简单使用

    Fabio(Go 语言):https://github.com/eBay/fabio Fabio 是一个快速.现代.zero-conf 负载均衡 HTTP(S) 路由器,用于部署 Consul 管理的 ...

  4. 在RedHat上安装gcc,java 和 eclipse-rcp

    本文全是如何用rpm包在红帽子54上安装gcc,automake,java和eclipse等,不是源代码编译,请大家不要误会了. 其实通过rpm包安装东西很简单,麻烦的是有很多rpm是要根据顺序进行先 ...

  5. [安卓]windows下如何安装Android源码

    本文改写于:http://www.cnblogs.com/skyme/archive/2011/05/14/2046040.html 1.下载并安装git: 在git-scm.com上下载并安装git ...

  6. 使用Antlr实现简单的DSL

    为什么要使用DSL DSL是领域专用语言,常见的DSL有SQL,CSS,Shell等等,这些DSL语言有别于其他通用语言如:C++,Java,C#,DSL常在特殊的场景或领域中使用.如下图: 领域专用 ...

  7. Weblogic环境下hibernate、antlr类加载冲突问题分析及解决方案

    公司应用项目在客户部署时经常遇到此类问题,为避免实施部署时增加配置量,花了点时间找到了此问题的终极解决办法(方案二.修改org.hibernate.hql.ast.HqlLexer的源代码).在此进行 ...

  8. 开源解析器--ANTLR

      序言 有的时候,我还真是怀疑过上本科时候学的那些原理课究竟是不是在浪费时间.比方学完操作系统原理之后我们并不能自己动手实现一个操作系统:学完数据库原理我们也不能弄出个像样的DBMS出来:相同,学完 ...

  9. 开源语法分析器--ANTLR

      序言 有的时候,我还真是怀疑过上本科时候学的那些原理课究竟是不是在浪费时间.比方学完操作系统原理之后我们并不能自己动手实现一个操作系统:学完数据库原理我们也不能弄出个像样的DBMS出来:相同,学完 ...

随机推荐

  1. MFC实现一元稀疏多项式运算器

    MFC实现一元稀疏多项式运算器 基本要求 输入并建立两个多项式 多项式a与b相加,建立和多项式c 多项式a与b相减,建立差多项式d 输出多项式a, b, c, d.输出格式:比如多项式a为:A(x)= ...

  2. CodeForces 1099F - Cookies - [DFS+博弈+线段树]

    题目链接:https://codeforces.com/problemset/problem/1099/F Mitya and Vasya are playing an interesting gam ...

  3. BZOJ 1001 - 狼抓兔子 - [Dinic最大流][对偶图最短路]

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1001 Description现在小朋友们最喜欢的"喜羊羊与灰太狼", ...

  4. 通用网关接口 ruby perl web页面 文本处理 脚本语言

    小结: 1.只要可以对标准输入输出进行操作,那么无论任何语言都可以编写CGI程序. <代码的未来> 在Ruby诞生的1993年,互联网还没有现在这样普及,因此Ruby也不是一开始就面向We ...

  5. gitignore 不起作用的解决办法

    gitignore 不起作用的解决办法 - sloong - 博客园 https://www.cnblogs.com/sloong/p/5523244.html Administrator@PC-20 ...

  6. iOS中的静态库与动态库,区别、制作和使用

    如果我们有些功能要给别人用,但是又不想公开代码实现,比如高德地图.第三方登录分享等等,这时候我们就要打包成库了.库分静态库和动态库两种: 静态库:以.a 和 .framework为文件后缀名.动态库: ...

  7. [knowledge] 停止等待协议

    再读TCP/IP详解 说到流量控制, 可能便涉及了两方面 1. 停止等待协议. https://baike.baidu.com/item/%E5%81%9C%E6%AD%A2%E7%AD%89%E5% ...

  8. [troubleshoot][daily][redhat] 设备反复重启故障排查

    一台服务器设备,反复重启,每天重启数次. 一: 原因分析及初步排异. 1.  硬件,内存主板,一一更换,甚至除了硬盘将整台机器都换掉了,依然重启. 2.  排除电源问题,换了电源线,换了插座,还是重启 ...

  9. [web][nginx] 初识nginx -- 使用nginx搭建https DPI解码测试环境

    环境 CentOS 7 X86 文档: https://nginx.org/en/docs/ 安装: [root@dpdk ~]# cat /etc/yum.repos.d/nginx.repo [n ...

  10. html5页面自适应移动端

    1. <!-- 这段代码的意思是,让 viewport 的宽度等于物理设备上的真实分辨率,不允许用户缩放,这样 dpi 肯定和设备上的真实分辨率是一样的,不做任何缩放,网页会因此显得更细腻. 1 ...