Java的隐秘之JavaCC
官网链接: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_BEGIN
到PARSER_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的魅力了?😊
更多精彩文章请访问GitHub博客
无特殊声明的文章均为原创!
原创文章如若转载,请注明出处!http://www.cnblogs.com/zqzjs/
告诫自己即使再累,也不要忘记学习。成功没有捷径可走,只有一步接着一步走下去!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
2016-09-08 javaScript的变量
2015-09-08 JavaScript权威设计--JavaScript类型,值,变量(简要学习笔记三)
2015-09-08 JavaScript权威设计--JavaScript词法结构(简要学习笔记二)
2015-09-08 JavaScript权威设计--JavaScript语言核心(简要学习笔记一)