官网链接:JavaCC

JavaCC


JavaCC是Java的解析器生成器兼扫描器生成器。为JavaCC描述好语法的规则,JavaCC就能够生成可以解析该语法的扫描器和解析器(的代码)了。

JavaCC是LL解析器生成器,因此比起LR解析器生成器和LALR解析器生成器,它有着可处理语法的范围相对狭哉的缺点。

但是,JavaCC生成的解析器有易于理解,易于使用的优势。且支持无限长的token超前扫描特性,所以速度非常的快。

巨坑


我为什么要把坑写在前面?因为这真的是太坑了!

一开始我下载的是官网的javacc-6.0,配置好环境变量后还是一只报错:

找不到或者无法加载主类 javacc

没错,官网的6.0版本有问题!于是使用javacc-5.0就好了。

具体参考:getting-started-with-javacc

编写语法描述文件


语法描述文件通常会使用.jj的后缀文件

语法描述文件的常用形式

options {
JavaCC 的选项
} PARSER_BEGIN(解析器类名)
package 包名;
import 库名; public class 解析器类名 {
任意的Java代码
}
PARSER_END (解析器类名) 扫描器的描述 解析器的描述

实例编写

Person.jj(文件名称可以任意命名)

options {
STATIC = false;
} PARSER_BEGIN(Person)
import java.io.*; class Person {
static public void main (String[] args) {
for (String arg : args) {
try {
System.out.println(evaluate(arg));
}
catch (ParseException ex) {
System.err.println(ex.getMessage);
}
}
} static public long evaluate (String src) throws ParseException {
Reader reader = new StringReader(src);
return new Person(reader).expr();
}
}
PARSER_END(Person) SKIP: { < [" ","\t","\r","\n"] > } TOKEN: {
<INTEGER: (["0"-"9"])+>
} long expr(): {
Token x,y;
}
{
x=<INTEGER> "+" y=<INTEGER> <EOF>
{
return Long.parseLong(x.image) + Long.parseLong(y.image);
}
}

具体分析:

  • options块中,将STATIC选项设置为false的意思是解析器可以在多线程环境下使用。设置为true亦反。
  • PARSER_BEGINPARSER_END是解析器类的定义。解析器类中需要定义的成员和方法也写在这。为了实现及时只有Person类也能够运行,这里定义类main函数。
  • SKIP和TOKEN部分定义类扫描器。SKIP表示要跳过空格,制表符和换行符。TOKEN表示扫描整数字符并生成TOKEN。
  • 从long expr...开始到最后的部分定义了狭义的解析器。这部分解析token序列并执行某些操作。

使用JavaCC来处理语法描述文件Person.jj

命令如下:

javacc Person

如果描述文件有问题,处理的时候会报错:

➜  java javacc Person.jj
Java Compiler Compiler Version 5.0 (Parser Generator)
(type "javacc" with no arguments for help)
Reading from file Person.jj . . .
org.javacc.parser.ParseException: Encountered " ";" "; "" at line 33, column 12.
Was expecting one of:
"throws" ...
":" ...

处理成功后类似:

➜  java javacc Person.jj
Java Compiler Compiler Version 5.0 (Parser Generator)
(type "javacc" with no arguments for help)
Reading from file Person.jj . . .
File "TokenMgrError.java" does not exist. Will create one.
File "ParseException.java" does not exist. Will create one.
File "Token.java" does not exist. Will create one.
File "SimpleCharStream.java" does not exist. Will create one.
Parser generated successfully.

除了生成Person.java文件以外,还会生成其他的辅助类,如ParseException

编译Person.java文件

这应该就很熟悉了

javac Person.java

生成.class文件。大功告成!

执行java文件

命令如下

➜  java java Person '111 + 222'
333

计算结果没毛病!

所以我们编写的语法规则,现在已经可以正常的计算了。

是不是体会到JavaCC的魅力了?

Java的隐秘之JavaCC的更多相关文章

  1. java开源模板引擎

      Velocity  Velocity是一个基于java的模板引擎(template engine).它允许任何人仅仅简单的使用模板语言(template language)来引用由java代码定义 ...

  2. antlr v4 使用指南连载1——简介

    antlr v4简介        antlr是一个强大语言解析工具,可以用于处理结构化文本.二进制文件.说白了,其实可以这么认为,antlr是一个更强大的正则表达式工具.它可以完成更多正则表达式无法 ...

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

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

  4. Spark案例分析

    一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...

  5. Java资源大全中文版(Awesome最新版)

    Awesome系列的Java资源整理.awesome-java 就是akullpp发起维护的Java资源列表,内容包括:构建工具.数据库.框架.模板.安全.代码分析.日志.第三方库.书籍.Java 站 ...

  6. Java工程师成神之路

    学习Java的同学注意了!!! 学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群,群号码:279558494 我们一起学Java! 一.基础篇 1.1 JVM 1.1.1. J ...

  7. 国外程序员整理的Java资源大全分享

    Java 几乎是许多程序员们的入门语言,并且也是世界上非常流行的编程语言.国外程序员 Andreas Kull 在其 Github 上整理了非常优秀的 Java 开发资源,推荐给大家. 译文由 Imp ...

  8. 基于java平台的常用资源整理

    这里整理了基于java平台的常用资源 翻译 from :akullpp | awesome-java 大家一起学习,共同进步. 如果大家觉得有用,就mark一下,赞一下,或评论一下,让更多的人知道.t ...

  9. 完整全面的Java资源库(包括构建、操作、代码分析、编译器、数据库、社区等等)

    构建 这里搜集了用来构建应用程序的工具. Apache Maven:Maven使用声明进行构建并进行依赖管理,偏向于使用约定而不是配置进行构建.Maven优于Apache Ant.后者采用了一种过程化 ...

随机推荐

  1. P3258 [JLOI2014]松鼠的新家

    P3258 [JLOI2014]松鼠的新家倍增lca+树上差分,从叶子节点向根节点求前缀和,dfs求子树和即可,最后,把每次的起点和终点都. #include<iostream> #inc ...

  2. 浅谈solr

    Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口.用户可以通过http请求,向搜索引擎服务器提交一定格式的XML文件,生成索引:也可以通过Http Get操 ...

  3. Codeforces Round #530 (Div. 2)

    RANK :2252 题数 :3 补题: D - Sum in the tree 思路:贪心 把权值放在祖先节点上 ,预处理 每个节点保存 他与他儿子中 权值最小值即可. 最后会有一些叶子节点依旧为 ...

  4. [OC] 使用 cocoaPods 导入 AFNetworking

    AFNetworking的GitHub地址: https://github.com/AFNetworking/AFNetworking 假设我们建立了一个叫做AFNWlearning的工程. 1.打开 ...

  5. Redis自学笔记:1.简介

    博主教材:李子骅.人民邮电出版社.<redis入门指南> 博主操作系统系统:虚拟机Ubuntu16.04 博主redis版本:3.0.6 第1章:简介 redis是一个开源的.高性能的.基 ...

  6. BZOJ.3551.[ONTAK2010]Peaks加强版(Kruskal重构树 主席树)

    题目链接 \(Description\) 有n个座山,其高度为hi.有m条带权双向边连接某些山.多次询问,每次询问从v出发 只经过边权<=x的边 所能到达的山中,第K高的是多少. 强制在线. \ ...

  7. 2186 ACM 水题 int 向下取整

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=2186 扩展: #include <cstdio> 使用floor函数.floor(x)返回的是 ...

  8. Django 自定义模板语法

    from django import template from django.utils.safestring import mark_safe register = template.Librar ...

  9. ReactNative用指定的真机/模拟器运行项目

    使用模拟器运行项目: 命令行中React native项目目录下键入react-native run-ios会启动iOS模拟器, 默认是使用iPhone6,如果想要试用其他版本的模拟器则需要在reac ...

  10. centos 7 之nginx

    环境信息 [root@node1 ~]# cat /etc/redhat-release CentOS Linux release (Core) [root@node1 ~]# uname -r -. ...