官网链接: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. Python虚拟环境的安装和配置-virtualenv与windows下多个python版本共存

    Python虚拟环境的安装和配置-virtualenv与windows下多个python版本共存 windows下多个python版本共存 https://www.python.org/downloa ...

  2. codeforces148----E. Porcelain

    #include <iostream> #include <cstring> using namespace std; ; int s[maxn];//s[i]表示每行前i个数 ...

  3. Redis自学笔记:4.3进阶-排序

    4.3排序 4.3.1有序集合的集合操作 有序集合没有zinter和zunion命令,使用其他命令实现方法: multi zinterstore tempKey ... zrange tempKey ...

  4. BZOJ.4818.[SDOI2017]序列计数(DP 快速幂)

    BZOJ 洛谷 竟然水过了一道SDOI!(虽然就是很水...) 首先暴力DP,\(f[i][j][0/1]\)表示当前是第\(i\)个数,所有数的和模\(P\)为\(j\),有没有出现过质数的方案数. ...

  5. System.ServiceModel.AddressAccessDeniedException

    发生了 System.ServiceModel.AddressAccessDeniedException   HResult=0x80131501   Message=HTTP 无法注册 URL ht ...

  6. NOIP复习篇

    NOIP复习篇---枚举 --------------------------------------------------------------------------------------- ...

  7. [CF1131F] Asya And Kittens

    Description: 给定n个点的序列,一开始有n个块,每次将两个块合并,并告诉你这两个块中的一对元素,求一种可能的原序列 Hint: \(n \le 1.5*10^5\) Solution: 实 ...

  8. [USACO18DEC]The Cow Gathering

    Description: 给定一棵树,每次删去叶子,有m个限制,分别为(a,b)表示a需要比b先删,为每个点能否成为最后被删的点 Hint: \(n,m \le 10^5\) Solution: 手模 ...

  9. [jzoj]3777.最短路(shortest)

    Link https://jzoj.net/senior/#main/show/3777 Description 小Y最近学得了最短路算法,一直想找个机会好好练习一下.话虽这么说,OJ上最短路的题目都 ...

  10. 编程菜鸟的日记-初学尝试编程-寻找等长数组A与B(所含元素相同,顺序不同)相匹配的元素即a[i]=b[j]

    #include <iostream> using namespace std; void matching(int a[],int b[],int N) { int i=0; while ...