文章目录
- 总体流程
- 下载antlr代码生成器
- 写g4文件
- 执行命令
- 添加maven依赖
- 写编译代码
- 测试
总体流程
#mermaid-svg-2JvJCzlmwXuPqmKy{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-2JvJCzlmwXuPqmKy .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-2JvJCzlmwXuPqmKy .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-2JvJCzlmwXuPqmKy .error-icon{fill:#552222;}#mermaid-svg-2JvJCzlmwXuPqmKy .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-2JvJCzlmwXuPqmKy .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-2JvJCzlmwXuPqmKy .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-2JvJCzlmwXuPqmKy .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-2JvJCzlmwXuPqmKy .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-2JvJCzlmwXuPqmKy .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-2JvJCzlmwXuPqmKy .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-2JvJCzlmwXuPqmKy .marker{fill:#333333;stroke:#333333;}#mermaid-svg-2JvJCzlmwXuPqmKy .marker.cross{stroke:#333333;}#mermaid-svg-2JvJCzlmwXuPqmKy svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-2JvJCzlmwXuPqmKy p{margin:0;}#mermaid-svg-2JvJCzlmwXuPqmKy .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-2JvJCzlmwXuPqmKy .cluster-label text{fill:#333;}#mermaid-svg-2JvJCzlmwXuPqmKy .cluster-label span{color:#333;}#mermaid-svg-2JvJCzlmwXuPqmKy .cluster-label span p{background-color:transparent;}#mermaid-svg-2JvJCzlmwXuPqmKy .label text,#mermaid-svg-2JvJCzlmwXuPqmKy span{fill:#333;color:#333;}#mermaid-svg-2JvJCzlmwXuPqmKy .node rect,#mermaid-svg-2JvJCzlmwXuPqmKy .node circle,#mermaid-svg-2JvJCzlmwXuPqmKy .node ellipse,#mermaid-svg-2JvJCzlmwXuPqmKy .node polygon,#mermaid-svg-2JvJCzlmwXuPqmKy .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-2JvJCzlmwXuPqmKy .rough-node .label text,#mermaid-svg-2JvJCzlmwXuPqmKy .node .label text,#mermaid-svg-2JvJCzlmwXuPqmKy .image-shape .label,#mermaid-svg-2JvJCzlmwXuPqmKy .icon-shape .label{text-anchor:middle;}#mermaid-svg-2JvJCzlmwXuPqmKy .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-2JvJCzlmwXuPqmKy .rough-node .label,#mermaid-svg-2JvJCzlmwXuPqmKy .node .label,#mermaid-svg-2JvJCzlmwXuPqmKy .image-shape .label,#mermaid-svg-2JvJCzlmwXuPqmKy .icon-shape .label{text-align:center;}#mermaid-svg-2JvJCzlmwXuPqmKy .node.clickable{cursor:pointer;}#mermaid-svg-2JvJCzlmwXuPqmKy .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-2JvJCzlmwXuPqmKy .arrowheadPath{fill:#333333;}#mermaid-svg-2JvJCzlmwXuPqmKy .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-2JvJCzlmwXuPqmKy .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-2JvJCzlmwXuPqmKy .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-2JvJCzlmwXuPqmKy .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-2JvJCzlmwXuPqmKy .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-2JvJCzlmwXuPqmKy .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-2JvJCzlmwXuPqmKy .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-2JvJCzlmwXuPqmKy .cluster text{fill:#333;}#mermaid-svg-2JvJCzlmwXuPqmKy .cluster span{color:#333;}#mermaid-svg-2JvJCzlmwXuPqmKy div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-2JvJCzlmwXuPqmKy .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-2JvJCzlmwXuPqmKy rect.text{fill:none;stroke-width:0;}#mermaid-svg-2JvJCzlmwXuPqmKy .icon-shape,#mermaid-svg-2JvJCzlmwXuPqmKy .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-2JvJCzlmwXuPqmKy .icon-shape p,#mermaid-svg-2JvJCzlmwXuPqmKy .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-2JvJCzlmwXuPqmKy .icon-shape rect,#mermaid-svg-2JvJCzlmwXuPqmKy .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-2JvJCzlmwXuPqmKy .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-2JvJCzlmwXuPqmKy .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-2JvJCzlmwXuPqmKy :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#mermaid-svg-2JvJCzlmwXuPqmKy .download>*{fill:#e1f5fe!important;stroke:#01579b!important;stroke-width:2px!important;}#mermaid-svg-2JvJCzlmwXuPqmKy .download span{fill:#e1f5fe!important;stroke:#01579b!important;stroke-width:2px!important;}#mermaid-svg-2JvJCzlmwXuPqmKy .grammar>*{fill:#fff9c4!important;stroke:#fbc02d!important;stroke-width:2px!important;}#mermaid-svg-2JvJCzlmwXuPqmKy .grammar span{fill:#fff9c4!important;stroke:#fbc02d!important;stroke-width:2px!important;}#mermaid-svg-2JvJCzlmwXuPqmKy .generate>*{fill:#e8f5e9!important;stroke:#2e7d32!important;stroke-width:2px!important;}#mermaid-svg-2JvJCzlmwXuPqmKy .generate span{fill:#e8f5e9!important;stroke:#2e7d32!important;stroke-width:2px!important;}#mermaid-svg-2JvJCzlmwXuPqmKy .code>*{fill:#f3e5f5!important;stroke:#7b1fa2!important;stroke-width:2px!important;}#mermaid-svg-2JvJCzlmwXuPqmKy .code span{fill:#f3e5f5!important;stroke:#7b1fa2!important;stroke-width:2px!important;}#mermaid-svg-2JvJCzlmwXuPqmKy .test>*{fill:#ffebee!important;stroke:#c62828!important;stroke-width:2px!important;}#mermaid-svg-2JvJCzlmwXuPqmKy .test span{fill:#ffebee!important;stroke:#c62828!important;stroke-width:2px!important;}#mermaid-svg-2JvJCzlmwXuPqmKy .result>*{fill:#eceff1!important;stroke:#455a64!important;stroke-width:2px!important;stroke-dasharray:5 5!important;}#mermaid-svg-2JvJCzlmwXuPqmKy .result span{fill:#eceff1!important;stroke:#455a64!important;stroke-width:2px!important;stroke-dasharray:5 5!important;}
5. 测试验证
4. 项目开发与编译
3. 生成 Java 代码
2. 定义语法规则
1. 环境准备
开始
下载 ANTLR Java 生成器antlr-4.13.2-complete.jar
编写 json.g4 文件定义 Lexer 和 Parser 规则
包含: STRING, NUMBER, obj, arr, value 等规则
执行生成命令java -jar … -visitor json.g4
拷贝生成的 Java 文件到源代码包中
添加 Maven 依赖antlr4-runtime 4.9.3
编写 Main.java 编译代码实现 CharStream -> Lexer -> Parser -> Visitor/Print
准备测试数据 test.json
运行 Main 类
输出解析结果
示例输出:("name"="John","friends"={"Tom","Lily"})
下载antlr代码生成器
antlr java下载地址 https://github.com/antlr/antlr4/blob/master/doc/java-target.md
https://www.antlr.org/download/antlr-4.13.2-complete.jar
写g4文件
// 语法名称
grammar JSON;
// 解析器规则 (小写开头)
// 1. 入口规则:匹配任何合法的 JSON 值
json
: value
;
// 2. 定义 JSON 的值类型
value
: STRING # StringLiteral // 字符串
| NUMBER # NumberLiteral // 数字
| obj # JsonObject // 对象
| arr # JsonArray // 数组
| 'true' # TrueLiteral // 布尔值 true
| 'false' # FalseLiteral // 布尔值 false
| 'null' # NullLiteral // null 值
;
// 3. 定义 JSON 对象结构 { key: value, … }
obj
: '{' pair (',' pair)* '}'
| '{' '}' // 空对象
;
// 4. 定义键值对结构
pair
: STRING ':' value
;
// 5. 定义数组结构 [ value, value, … ]
arr
: '[' value (',' value)* ']'
| '[' ']' // 空数组
;
// 6. 词法分析规则 (大写开头)
// 字符串:双引号包围,支持转义字符
STRING
: '"' (ESC | ~["\\\\])* '"'
;
// 数字:支持负数、小数、科学计数法
NUMBER
: '-'? INT ('.' [0-9]+)? EXP?
;
// 跳过空白字符 (空格, 换行, 制表符)
WS
: [ \\t\\n\\r]+ -> skip
;
// 片段规则 (仅供其他词法规则使用,不会单独匹配)
// 转义字符处理
fragment ESC
: '\\\\' ["\\\\/bfnrt]
| UNICODE_ESCAPE
;
// Unicode 转义
fragment UNICODE_ESCAPE
: '\\\\' 'u' HEX HEX HEX HEX
;
// 十六进制字符
fragment HEX
: [0-9a-fA-F]
;
// 整数部分
fragment INT
: '0'
| [1-9] [0-9]*
;
// 科学计数法
fragment EXP
: [Ee] [+-]? [0-9]+
;
执行命令
java -jar .\\antlr-4.13.2-complete.jar -visitor json.g4
然后将获得的java文件拷贝到源代码相应的包中。
添加maven依赖
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>4.9.3</version>
</dependency>
写编译代码
package cn.edu.ncepu.antlr;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.ParseTree;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.List;
/**
* 测试
* 2026-03-02
*
* @author 醒过来摸鱼
*/
public class Main {
public static void main(String[] args) throws IOException {
CharStream input = CharStreams.fromPath(Paths.get("antlr-learn/test.json"));
JSONLexer lexEngine = new JSONLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexEngine);
JSONParser jsonParser = new JSONParser(tokens);
JSONParser.JsonContext json = jsonParser.json();
System.out.println(print(json.value()));
}
private static String print(ParserRuleContext json) {
if (json instanceof JSONParser.StringLiteralContext string) {
return string.STRING().toString();
}
if (json instanceof JSONParser.JsonArrayContext jsonArrayContext) {
return print(jsonArrayContext.arr());
}
if (json instanceof JSONParser.JsonObjectContext jsonObjectContext) {
return print(jsonObjectContext.obj());
}
if (json instanceof JSONParser.PairContext pairContext) {
return pairContext.STRING()+ "=" + print(pairContext.value());
}
if (json instanceof JSONParser.ArrContext arrContext) {
List<JSONParser.ValueContext> value = arrContext.value();
StringBuilder builder = new StringBuilder("{");
boolean first = true;
for (JSONParser.ValueContext valueContext : value) {
String print = print(valueContext);
if (print != null && !print.isBlank()) {
if (first) {
first = false;
} else {
builder.append(",");
}
builder.append(print);
}
}
builder.append("}");
return builder.toString();
}
StringBuilder builder = new StringBuilder("(");
boolean first = true;
for (int i = 0; i < json.getChildCount(); i++) {
ParseTree child = json.getChild(i);
if (child instanceof ParserRuleContext context) {
String print = print(context);
if (print != null && !print.isBlank()) {
if (first) {
first = false;
} else {
builder.append(",");
}
builder.append(print);
}
}
}
builder.append(")");
return builder.toString();
}
}
测试
我使用的测试数据如下:
{
"name": "John",
"friends": ["Tom", "Lily"]
}
测试结果:
("name"="John","friends"={"Tom","Lily"})
网硕互联帮助中心





评论前必须登录!
注册