基于antlr3的json分析器实现json到java业务对象转化_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 基于antlr3的json分析器实现json到java业务对象转化

基于antlr3的json分析器实现json到java业务对象转化

 2014/9/14 21:57:03  lishidi  程序员俱乐部  我要评论(0)
  • 摘要:分析json的方式有很多,使用antlr做json的分析在性能上肯定不怎么好,比较涉及到语法语义的分析,同时把json转成java对象的话,那么肯定要基于ast去做,所以在性能上肯定没有原生的好,这里只是提供一种解决思路,比较做原生的json分析,肯定用antlr的话更加的直观一点,下面是antlr的两个分析文件的内容首先是普通解析器的语法文件grammarJSON;options{backtrack=true;memoize=true;output=AST
  • 标签:实现 Java 分析 JSON Ant JS

分析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>

只有一个依赖包

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

  • com.rar (19.6 KB)
  • 下载次数: 0
发表评论
用户名: 匿名