分析json的方式有很多,使用antlr做json的分析在性能上肯定不怎么好,比较涉及到语法语义的分析,同时把json转成java对象的话,那么肯定要基于ast去做,所以在性能上肯定没有原生的好,这里只是提供一种解决思路,比较做原生的json分析,肯定用antlr的话更加的直观一点,下面是antlr的两个分析文件的内容
首先是普通解析器的语法文件
grammar JSON;
options
{
backtrack=true;
memoize=true;
output=AST;
ASTLabelType=CommonTree;
k=1;
}
tokens
{
OBJECT;
ELEMENT;
ARRAY;
STRING;
INTEGER;
DOUBLE;
}
@lexer::header
{
package com.test.json.antlr3;
}
@header
{
package com.test.json.antlr3;
}
@lexer::members{
List errorList = new ArrayList();
public void displayRecognitionError(String[] tokenNames,
RecognitionException e) {
String hdr = getErrorHeader(e);
String msg = getErrorMessage(e, tokenNames);
errorList.add(hdr+" "+msg);
}
}
@members
{
List errorList = new ArrayList();
public void displayRecognitionError(String[] tokenNames,
RecognitionException e) {
String hdr = getErrorHeader(e);
String msg = getErrorMessage(e, tokenNames);
errorList.add(hdr+" "+msg);
}
}
// lexer rules
Colon: ':';
Comma: ',';
LBrace: '{';
RBrace: '}';
LBracket: '[';
RBracket: ']';
fragment Dot: '.';
TRUE: 'true';
FALSE: 'false';
NULL: 'null';
DOUBLE_QUOTES :'"';
fragment Digit: '0' .. '9';
fragment HexDigit: ('0' .. '9' | 'A' .. 'F' | 'a' .. 'f');
fragment UnicodeChar: ~('"'| '\\' );
fragment StringChar : ('a'..'z'|'A'..'Z'|'0'..'9'|'_')+;
fragment EscapeSequence
: '\\' ('\"' | '\\' | '/' | 'b' | 'f' | 'n' | 'r' | 't' | 'u' HexDigit HexDigit HexDigit HexDigit)
;
fragment Int: '-'? ('0' | '1'..'9' Digit*);
fragment Frac: Dot Digit+;
fragment Exp: ('e' | 'E') ('+' | '-')? Digit+;
WhiteSpace: (' ' | '\r' | '\t' | '\u000C' | '\n') { $channel=HIDDEN; };
Integer: Int;
Double: Int (Frac Exp? | Exp);
StringLiteral
: '"' ( EscapeSequence | ~('\\'|'"') )* '"'
;
String: DOUBLE_QUOTES StringLiteral* DOUBLE_QUOTES;
IDENTIFIER
:
StringChar*
;
jsonObject
: object
;
jsonArray
: array
;
object
: LBrace (objectElement (Comma objectElement)*)? RBrace
;
objectElement
:
(StringLiteral
|
IDENTIFIER
)
Colon value
;
array
: LBracket value (Comma value)* RBracket
;
value
: StringLiteral
| Integer
| Double
| object
| array
| TRUE
| FALSE
| NULL
;
antlr3的tree grammar的内容
tree grammar JSONWalker;
options
{
backtrack=true;
memoize=true;
output=AST;
ASTLabelType=CommonTree;
tokenVocab=JSON;
k=1;
}
@header {
package com.test.json.antlr3;
}
jsonObject
: object
;
jsonArray
: array
;
object
: LBrace (objectElement (Comma objectElement)*)? RBrace
-> ^(OBJECT objectElement*)
;
objectElement
: (StringLiteral
|
IDENTIFIER) Colon value
-> ^(ELEMENT StringLiteral? IDENTIFIER? value)
;
array
: LBracket value (Comma value)* RBracket
-> ^(ARRAY value+)
;
value
: StringLiteral -> ^(STRING StringLiteral)
| Integer -> ^(INTEGER Integer)
| Double -> ^(DOUBLE Double)
| object
| array
| TRUE
| FALSE
| NULL
;
通过antlr的tool工具生成解析器,为了方便可以写一个ant脚本去实现,具体如下
<java classname="org.antlr.Tool"
fork="true"
failonerror="false"
maxmemory="256m"
>
<classpath>
<pathelement path="${maven}/org/antlr/antlr-complete/3.5.2/antlr-complete-3.5.2.jar" />
</classpath>
<arg value="-o"/>
<arg value="${projectpath}/src/main/java/com/test/json/antlr3"/>
<arg value="-print"/>
<arg value="${projectpath}/grammar/JSON.g"/>
</java>
<java classname="org.antlr.Tool"
fork="true"
failonerror="false"
maxmemory="256m"
>
<classpath>
<pathelement path="${maven}/org/antlr/antlr-complete/3.5.2/antlr-complete-3.5.2.jar" />
</classpath>
<arg value="-o"/>
<arg value="${projectpath}/src/main/java/com/test/json/antlr3"/>
<arg value="-print"/>
<arg value="${projectpath}/grammar/JSONWalker.g"/>
</java>
有了ast语法树以后,剩下的就是要做分析,antlr3有两种方式处理ast语法树,一种是编写treeadapter(需要分析token流,对于我来说难度太大),一种是使用默认的,自己去做遍历,遍历的结果有两种一种是Object一种是Array,但是由于这个只是普通的json原生转化需要实例化具体的业务对象中,我采用先生成语法树,然后生成原生的Java的json对象,通过该对象转化到具体的业务对象中。
转化的过程涉及到了java反射,所以在性能优化上可以做一些缓存处理,在反射处理中使用sun里面的unsafer类,得到最后的转化效果代码如下
public static void main(String[] args) {
User user = JSON.parseObject("{username:null,contact:{mobile:\"1123111311\",qq:\"1231001884\",email:\"ceshi@126.com\"},address:[{email:\"test\",qq:\"419001231\"}]}", User.class);
System.out.println(user.getContact().getMobile()+" "+user.getContact().getEmail()+" "+user.getAddress());
}
把json里面的数据转化成user对象,具体实现可以实例代码
如果要做测试,加入maven的依赖包
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr-complete</artifactId>
<version>3.5.2</version>
</dependency>
</dependencies>
只有一个依赖包
相关推荐
3. **语法分析**:接着,ANTLR4生成的解析器(Parser)会根据词法分析器产生的tokens来构造JSON数据的抽象语法树(AST,Abstract Syntax Tree)。这有助于我们理解输入数据的结构,并方便后续的处理。 4. **参考...
ANTLR被广泛应用于各种编程语言的编译器和解释器的开发,它能生成Java、C#、Python、JavaScript等多种目标语言的解析器和词法分析器。ANTLR4是其最新版本,提供了更高的性能和更易用的语法规则定义。 ANTLR的主要...
ANTLR生成Java、C#、Python、JavaScript等多种语言的解析器和词法分析器,使得开发者能够轻松地处理各种输入语法。 在Java领域,ANTLR被用来构建语法解析器,特别是对于那些需要解析自定义语法的项目。它可以解析...
3. **编译器与解析器**:Jaql的查询字符串需要转化为可执行的结构,这可能涉及词法分析(lexer)和语法分析(parser)的实现,如使用ANTLR等工具生成解析器。 4. **遍历与操作**:Jaql的查询需要遍历JSON对象并执行...
在本例中,"antlr-runtime-3.5.1.zip" 提供的是ANTLR运行时库的版本3.5.1,这个库包含了ANTLR生成的解析器和词法分析器在实际应用中运行所需要的组件。 JSON(JavaScript Object Notation)是一种轻量级的数据交换...
ANTLR(ANother Tool for Language Recognition,另一个语言识别工具)是一种强大的解析器生成器,用于读取、处理、执行或翻译结构化的文本或二进制文件。ANTLR 广泛应用于 DSL(领域特定语言)、文本解析、数学计算...
5. 类和对象:如果涉及到面向对象的语言,会包含类、对象、继承等概念。 6. 错误处理:如何在语法错误发生时提供有用的反馈信息。 7. 注释处理:如何忽略注释部分,不影响解析过程。 通过这些示例,学习者可以理解...
3. **词法分析器生成**:ANTLR同时生成词法分析器,将输入的字符流分解为一个个的词素(token)。 4. **树解析器**:ANTLR支持生成抽象语法树(AST),方便对语法结构进行处理和操作。 5. **错误处理**:ANTLR提供了...
ANTLR的应用场景非常广泛,比如构建自定义编程语言、解析配置文件、实现SQL查询解析、构建XML/JSON解析器等。它不仅可以用于学术研究,也是许多工业级项目中的首选工具。通过学习ANTLR,开发者可以更高效地处理结构...
在学习ANTLR v4的过程中,读者可以了解到解析器的内部工作机制,包括词法分析器和语法分析器的构建。同时,ANTLR v4支持不同类型的解析技术,如LL(*)、LR和自定义解析,这对于处理不同复杂度的语法特别有用。 ANTLR...
在Python环境中,ANTLR提供了一个Python运行时库,使得开发者能够在Python中方便地使用ANTLR生成的解析器和词法分析器。 ANTLR的工作原理是基于上下文无关语法(Context-Free Grammar, CFG),允许用户定义一套语法...
2. **生成语法分析器代码**:使用ANTLR工具生成对应的Java或C#语法分析器代码。例如,在命令行中输入`antlr4 E.g -Dlanguage=Java`即可生成Java版本的语法分析器代码。 3. **编译运行语法分析器**:使用相应的编程...
ANTLR生成Java、C#、Python、JavaScript等语言的解析器和词法分析器,支持LL(*)和LR语法分析策略。这个"antlr4-python3-runtime-4.8.tar.gz"文件是ANTLR针对Python 3的运行时库版本4.8的压缩包。 ANTLR的主要功能...
ANTLR(Another Tool for Language Recognition)是一种强大的语法分析工具,用于读取、处理、执行或翻译结构化文本或二进制文件。它广泛应用于编程语言、协议和其他格式的语言识别场景中。ANTLR版本4是该工具的一个...
综上所述,书中对ANTLR的介绍不仅仅是工具使用层面,还包括了如何设计语法、构建词法分析器和解析器,以及如何将解析器生成的代码应用到实际项目中。此外,通过真实世界的例子来帮助读者更好地理解ANTLR的具体应用,...
ANTLR4是一个强大的解析器生成器,它可以生成Java、C#、Python等多种语言的解析器和词法分析器。ANTLR4支持LL(*)和LALR(1)解析策略,能够处理复杂的语法规则,并且提供了一种灵活的语法描述语言——ANTLR语法文件(....