文章目录总体流程下载antlr代码生成器写g4文件执行命令添加maven依赖写编译代码测试总体流程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 类输出解析结果示例输出:(nameJohn,friends{Tom,Lily})下载antlr代码生成器antlr java下载地址https://github.com/antlr/antlr4/blob/master/doc/java-target.mdhttps://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依赖dependencygroupIdorg.antlr/groupIdartifactIdantlr4-runtime/artifactIdversion4.9.3/version/dependency写编译代码packagecn.edu.ncepu.antlr;importorg.antlr.v4.runtime.*;importorg.antlr.v4.runtime.tree.ParseTree;importjava.io.IOException;importjava.nio.file.Paths;importjava.util.List;/** * 测试 * 2026-03-02 * * author 醒过来摸鱼 */publicclassMain{publicstaticvoidmain(String[]args)throwsIOException{CharStreaminputCharStreams.fromPath(Paths.get(antlr-learn/test.json));JSONLexerlexEnginenewJSONLexer(input);CommonTokenStreamtokensnewCommonTokenStream(lexEngine);JSONParserjsonParsernewJSONParser(tokens);JSONParser.JsonContextjsonjsonParser.json();System.out.println(print(json.value()));}privatestaticStringprint(ParserRuleContextjson){if(jsoninstanceofJSONParser.StringLiteralContextstring){returnstring.STRING().toString();}if(jsoninstanceofJSONParser.JsonArrayContextjsonArrayContext){returnprint(jsonArrayContext.arr());}if(jsoninstanceofJSONParser.JsonObjectContextjsonObjectContext){returnprint(jsonObjectContext.obj());}if(jsoninstanceofJSONParser.PairContextpairContext){returnpairContext.STRING()print(pairContext.value());}if(jsoninstanceofJSONParser.ArrContextarrContext){ListJSONParser.ValueContextvaluearrContext.value();StringBuilderbuildernewStringBuilder({);booleanfirsttrue;for(JSONParser.ValueContextvalueContext:value){Stringprintprint(valueContext);if(print!null!print.isBlank()){if(first){firstfalse;}else{builder.append(,);}builder.append(print);}}builder.append(});returnbuilder.toString();}StringBuilderbuildernewStringBuilder(();booleanfirsttrue;for(inti0;ijson.getChildCount();i){ParseTreechildjson.getChild(i);if(childinstanceofParserRuleContextcontext){Stringprintprint(context);if(print!null!print.isBlank()){if(first){firstfalse;}else{builder.append(,);}builder.append(print);}}}builder.append());returnbuilder.toString();}}测试我使用的测试数据如下{name:John,friends:[Tom,Lily]}测试结果(nameJohn,friends{Tom,Lily})