`

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

阅读更多

分析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)
  • 下载次数: 11
分享到:
评论
1 楼 shiyuan1551 2014-09-18  
引用
[u][/u]

相关推荐

    antlr4-json-parser.zip

    3. **语法分析**:接着,ANTLR4生成的解析器(Parser)会根据词法分析器产生的tokens来构造JSON数据的抽象语法树(AST,Abstract Syntax Tree)。这有助于我们理解输入数据的结构,并方便后续的处理。 4. **参考...

    antlr.jar和json.jar

    ANTLR被广泛应用于各种编程语言的编译器和解释器的开发,它能生成Java、C#、Python、JavaScript等多种目标语言的解析器和词法分析器。ANTLR4是其最新版本,提供了更高的性能和更易用的语法规则定义。 ANTLR的主要...

    antlr java语法分析程序

    ANTLR生成Java、C#、Python、JavaScript等多种语言的解析器和词法分析器,使得开发者能够轻松地处理各种输入语法。 在Java领域,ANTLR被用来构建语法解析器,特别是对于那些需要解析自定义语法的项目。它可以解析...

    基于Java的实例开发源码-JSON查询语言 Jaql.zip

    3. **编译器与解析器**:Jaql的查询字符串需要转化为可执行的结构,这可能涉及词法分析(lexer)和语法分析(parser)的实现,如使用ANTLR等工具生成解析器。 4. **遍历与操作**:Jaql的查询需要遍历JSON对象并执行...

    antlr-runtime-3.5.1.zip

    在本例中,"antlr-runtime-3.5.1.zip" 提供的是ANTLR运行时库的版本3.5.1,这个库包含了ANTLR生成的解析器和词法分析器在实际应用中运行所需要的组件。 JSON(JavaScript Object Notation)是一种轻量级的数据交换...

    Antlr入门介绍小demo

    ANTLR(ANother Tool for Language Recognition,另一个语言识别工具)是一种强大的解析器生成器,用于读取、处理、执行或翻译结构化的文本或二进制文件。ANTLR 广泛应用于 DSL(领域特定语言)、文本解析、数学计算...

    antlr 例子集 v3版

    5. 类和对象:如果涉及到面向对象的语言,会包含类、对象、继承等概念。 6. 错误处理:如何在语法错误发生时提供有用的反馈信息。 7. 注释处理:如何忽略注释部分,不影响解析过程。 通过这些示例,学习者可以理解...

    ANTLR的一些资料

    3. **词法分析器生成**:ANTLR同时生成词法分析器,将输入的字符流分解为一个个的词素(token)。 4. **树解析器**:ANTLR支持生成抽象语法树(AST),方便对语法结构进行处理和操作。 5. **错误处理**:ANTLR提供了...

    ANTLR入门 中英文

    ANTLR的应用场景非常广泛,比如构建自定义编程语言、解析配置文件、实现SQL查询解析、构建XML/JSON解析器等。它不仅可以用于学术研究,也是许多工业级项目中的首选工具。通过学习ANTLR,开发者可以更高效地处理结构...

    The Definitive ANTLR 4 Reference

    在学习ANTLR v4的过程中,读者可以了解到解析器的内部工作机制,包括词法分析器和语法分析器的构建。同时,ANTLR v4支持不同类型的解析技术,如LL(*)、LR和自定义解析,这对于处理不同复杂度的语法特别有用。 ANTLR...

    antlr的python运行时库

    在Python环境中,ANTLR提供了一个Python运行时库,使得开发者能够在Python中方便地使用ANTLR生成的解析器和词法分析器。 ANTLR的工作原理是基于上下文无关语法(Context-Free Grammar, CFG),允许用户定义一套语法...

    关于antlr的详细教材

    2. **生成语法分析器代码**:使用ANTLR工具生成对应的Java或C#语法分析器代码。例如,在命令行中输入`antlr4 E.g -Dlanguage=Java`即可生成Java版本的语法分析器代码。 3. **编译运行语法分析器**:使用相应的编程...

    antlr4-python3-runtime-4.8.tar.gz

    ANTLR生成Java、C#、Python、JavaScript等语言的解析器和词法分析器,支持LL(*)和LR语法分析策略。这个"antlr4-python3-runtime-4.8.tar.gz"文件是ANTLR针对Python 3的运行时库版本4.8的压缩包。 ANTLR的主要功能...

    Pragmatic.The Definitive ANTLR 4 Reference.2013.pdf

    ANTLR(Another Tool for Language Recognition)是一种强大的语法分析工具,用于读取、处理、执行或翻译结构化文本或二进制文件。它广泛应用于编程语言、协议和其他格式的语言识别场景中。ANTLR版本4是该工具的一个...

    Pragmatic.The Definitive ANTLR 4 Reference.2013

    综上所述,书中对ANTLR的介绍不仅仅是工具使用层面,还包括了如何设计语法、构建词法分析器和解析器,以及如何将解析器生成的代码应用到实际项目中。此外,通过真实世界的例子来帮助读者更好地理解ANTLR的具体应用,...

    ts-parser:使用ANTLR4生成的TypeScript解析器

    ANTLR4是一个强大的解析器生成器,它可以生成Java、C#、Python等多种语言的解析器和词法分析器。ANTLR4支持LL(*)和LALR(1)解析策略,能够处理复杂的语法规则,并且提供了一种灵活的语法描述语言——ANTLR语法文件(....

Global site tag (gtag.js) - Google Analytics