解析器生成器之 JavaCC(1): JavaCC 准备篇
Author: stormQ
Created: Saturday, 27. February 2021 10:15PM
Last Modified: Saturday, 06. March 2021 10:17AM
本文简单地介绍了 JavaCC 的特性,并描述了安装和运行 JavaCC 的具体步骤。除此之外,初步介绍了 JavaCC 的语法描述文件。从而,为后面学习基于 JavaCC 生成扫描器和解析器做好准备。
JavaCC 是一种解析器生成器(兼扫描器生成器)。其特点如下表所示。
JavaCC | 描述 |
---|---|
支持生成哪些语言的解析器 | 仅支持 Java |
所生成解析器的特点 | |
如何描述词法规则 | 采用正则表达式 |
如何描述语法规则 | 采用 EBNF 表示法 |
注:
LL
解析器的速度较快,但可以处理的语法范围相对狭窄。JavaCC 通过支持“无限长的 token 超前扫描”,很好地改善了该问题。
JavaCC 默认生成LL(1)
解析器,但也支持生成LL(k)
解析器。
EBNF (Extended Backus -Naur Form,巴科斯-诺尔范式),也是用来描述语法规则的,比正则表达式描述的语法范围更广。
本节描述了在 Ubuntu 20.04 系统中安装并运行 JavaCC 的具体步骤。
step 1: 安装 java 运行环境
在 Ubuntu 20.04 系统中,安装命令如下:
$ sudo apt install default-jre
step 2: 安装 JavaCC
在 Ubuntu 20.04 系统中,安装 JavaCC 的命令如下:
$ sudo apt install javacc
step 3: 运行 JavaCC
1) JavaCC 语法描述文件示例
sample.jj:
options {
STATIC = false;
}
PARSER_BEGIN(Dummy)
public class Dummy {
}
PARSER_END(Dummy)
SKIP: { <[" ","\t","\r","\n"]> }
TOKEN: {
<INTERGR: (["0"-"9"])+>
}
这里,先不用关心该语法描述文件的内容,后续文章会详细讲解。
2) 运行 JavaCC
要用 JavaCC 处理 sample.jj,执行如下命令:
$ javacc sample.jj
中间过程输出如下:
Java Compiler Compiler Version 5.0 (Parser Generator)
(type "javacc" with no arguments for help)
Reading from file ../sample.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.
生成的文件如下:
DummyConstants.java ParseException.java TokenMgrError.java
Dummy.java SimpleCharStream.java
DummyTokenManager.java Token.java
JavaCC 的语法描述文件以.jj
结尾。一般情况下,其内容多采用如下形式:
options {
JavaCC 的选项
}
PARSER_BEGIN(解析器类名)
package 包名
import 库名
public class 解析器类名 {
任意的 Java 代码
}
PARSER_END(解析器类名)
扫描器的描述
解析器的描述
注:
options
部分,用于放置 JavaCC 的选项。常用选项见下文中的 JavaCC 语法描述文件中的 options。
PARSER_BEGIN、PARSER_END
部分,用于定义解析器类。解析器类中需要定义的成员和方法都写在这里。
扫描器的描述
部分,用于定义扫描器。
解析器的描述
部分,用于定义解析器。
注意:
PARSER_BEGIN、PARSER_END
部分不能省略,并且只能有一个。
将扫描器的描述
部分放到PARSER_BEGIN
前面时,JavaCC 会报错。
JavaCC 语法描述文件所支持的 options 可以用javacc
命令查看。常用的 options 及其含义如下。
options | 作用 | 取值及含义 | 在语法描述文件中如何书写 |
---|---|---|---|
STATIC | 用于决定 JavaCC 生成的所有成员及方法是否都被定义为 static(注意: 定义为 static 后,JavaCC 所生成的解析器无法在多线程环境下使用) | STATIC = false;(以英文分号结尾) | |
UNICODE_INPUT | 用于决定是否支持处理带有中文的字符串 | UNICODE_INPUT = true; |
另外,options 也可以在执行 JavaCC 时指定。如下:
$ javacc -DEBUG_PARSER=false sample.jj
需要注意的是, 如果同一个 option 既在语法描述文件中指定了,也在执行 JavaCC 时指定了,并且这两处所指定的值不同,那么 JavaCC 会选择后者所指定的的值。
下一篇:解析器生成器之 JavaCC(2):如何基于 JavaCC 描述扫描器
上一篇:自制编译器之目录