网站首页 > 博客文章 正文
JSON (JavaScript Object Notation) 是一个轻量级的数据交互格式,对人类读写比较友好,并且生成和解析比较简单。是WEB传输和系统交互常用的数据格式。
JSON的数据格式比较简单,有两种结构:键值对的集合或者是值的数组,这两种格式又可以相互嵌套,下面是个简单的JSON字符串:
//{"persion":{"addr":[{"com":"北京朝阳"},{"home":"山东济南"}],"age":12,"name":"张三"}}
{
"persion": {
"addr": [
{
"com": "北京朝阳"
},
{
"home": "山东济南"
}
],
"age": 12,
"name": "张三"
}
}
下面使用ANTLR解析JSON字符串,如果不了解怎么安装ANLTR,请参考从零开始学习ANTLR4,Windows下搭建环境。
首先需要获取JSON的语法文件,如果不想自己写语法文件,可以在GITHUB上搜索"grammars-v4",然后找到JSON.g4文件即可,以下就是最新版本的JSON.g4。
//JOSN.g4
grammar JSON;
json
: value EOF
;
obj
: '{' pair (',' pair)* '}'
| '{' '}'
;
pair
: STRING ':' value
;
arr
: '[' value (',' value)* ']'
| '[' ']'
;
value
: STRING
| NUMBER
| obj
| arr
| 'true'
| 'false'
| 'null'
;
STRING
: '"' (ESC | SAFECODEPOINT)* '"'
;
fragment ESC
: '\\' (["\\/bfnrt] | UNICODE)
;
fragment UNICODE
: 'u' HEX HEX HEX HEX
;
fragment HEX
: [0-9a-fA-F]
;
fragment SAFECODEPOINT
: ~ ["\\\u0000-\u001F]
;
NUMBER
: '-'? INT ('.' [0-9] +)? EXP?
;
fragment INT
// integer part forbis leading 0s (e.g. `01`)
: '0' | [1-9] [0-9]*
;
// no leading zeros
fragment EXP
// exponent number permits leading 0s (e.g. `1e01`)
: [Ee] [+\-]? [0-9]+
;
// \- since - means "range" inside [...]
WS
: [ \t\n\r] + -> skip
;
下面就可以生成对应的Java文件了,有两种方式,一种是插件方式,一种是命令行模式,如果不熟悉也可以参考从零开始学习ANTLR4,Windows下搭建环境,下图就是生成后的文件:
先使用TestRig来生成语法树,TestRig是ANTLR内置的一个语法调试工具,使用参数-gui生成可视化的语法树:
java -cp .;./antlr-4.9.3-complete.jar org.antlr.v4.gui.TestRig JSON json -gui
{"persion":{"addr":[{"com":"北京朝阳"},{"home":"山东济南"}],"age":12,"name":"张三"}}
重点来了,使用测试程序来校验JSON的正确性,ANTLR内置了一个错误监听器ConsoleErrorListener,如果语法错误的时候会在控制台输出错误信息,还是使用上面的JSON字符串测试,先使用正确的格式测试,最终输出一颗正确语法树,并且没有输入语法错误信息。
package antlr4.json;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
public class TestJson {
public static void main(String[] args) {
String jsonStr = "{\"persion\":{\"addr\":[{\"com\":\"北京朝阳\"},{\"home\":\"山东济南\"}],\"age\":12,\"name\":\"张三\"}}";
CharStream charStream = CharStreams.fromString(jsonStr);
JSONLexer jsonLexer = new JSONLexer(charStream);
CommonTokenStream commonTokenStream = new CommonTokenStream(jsonLexer);
//语法分析器
JSONParser jsonParser = new JSONParser(commonTokenStream);
JSONParser.JsonContext jsonContext = jsonParser.json();
//打印语法树
System.out.println(jsonContext.toStringTree(jsonParser));
}
}
//输出结果
(json (value (obj { (pair "persion" : (value (obj { (pair "addr" : (value (arr [ (value (obj { (pair "com" : (value "北京朝阳")) })) , (value (obj { (pair "home" : (value "山东济南")) })) ]))) , (pair "age" : (value 12)) , (pair "name" : (value "张三")) }))) })) <EOF>)
把JSON稍微改一下,删除最后的一个},测试结果如下,在控制台打印JSON语法的错误信息,你还会发现此时也打印了一颗语法树,但是这个语法树跳过了最后的词法符合}。如果有必要可以实现自定义的错误监听器,只要在解析前添加到语法分析器中即可,有时间的可以试试。
//JSON: {"persion":{"addr":[{"com":"北京朝阳"},{"home":"山东济南"}],"age":12,"name":"张三"}
line 1:73 mismatched input '<EOF>' expecting {',', '}'}
(json (value (obj { (pair "persion" : (value (obj { (pair "addr" : (value (arr [ (value (obj { (pair "com" : (value "北京朝阳")) })) , (value (obj { (pair "home" : (value "山东济南")) })) ]))) , (pair "age" : (value 12)) , (pair "name" : (value "张三")) }))))) <EOF>)
- 上一篇: JSON 可视化工具,更直观更易用
- 下一篇: 比较工具大集合
猜你喜欢
- 2024-12-05 比较工具大集合
- 2024-12-05 JSON 可视化工具,更直观更易用
- 2024-12-05 5个图表在线制作网站,让你的数据会说话
- 2024-12-05 python接口自动化(九)--python中字典和json的区别(详解)
- 2024-12-05 现代配置指南——YAML 比 JSON 高级在哪
- 2024-12-05 git diff 知道吧?请说说实现原理
- 2024-12-05 GroupDocs.Comparison新版发布-添加了多种格式的文本对比
- 2024-12-05 JSON Hero功能强大的JSON查看工具
你 发表评论:
欢迎- 08-03 Docker 命令入门实战:搞懂这些才算真正入门!
- 08-03Docker 常用命令分类汇总
- 08-03docker常用命令大全,看这一篇就够了
- 08-03Docker命令大全详解(39个常用命令)
- 08-03Docker 常用命令手册
- 08-03Docker命令最全详解(39个最常用命令)
- 08-03Docker命令最全详解(29个最常用命令)
- 08-03C++语法进阶-字符:字符变量(char)
- 最近发表
- 标签列表
-
- ifneq (61)
- 字符串长度在线 (61)
- googlecloud (64)
- flutterrun (59)
- powershellfor (73)
- messagesource (71)
- plsql64位 (73)
- vueproxytable (64)
- npminstallsave (63)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- nacos启动失败 (64)
- ssh-add (70)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- qcombobox样式表 (68)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)