使用antlr建立灵活的配置

antlr是个不错的基于java的编译生成器。当你需要某个灵活的配置时,可以通过它定义自己的语言、语法解析过程。

例如:

<check condition="!( power(501) || power(506) )" msg="aaaa"/> //条件为true出aaaa

<check condition="use('T',11) && power(506) " msg="bbbb"/> //条件为true出bbbb

 

  • 语法实现PowserCheck3.g

grammar PowserCheck3; options { language=Java; //backtrack=true; } tokens { AND = '&&' ; OR = '||' ; NOT = '!' ; } @header { package com.lingtong.checkbox; import java.io.IOException; import java.util.LinkedList; import java.util.Vector; } @lexer::header { package com.lingtong.checkbox; } /*------------------------------------------------------------------ * PARSER RULES *------------------------------------------------------------------*/ prog returns [IBooleanNode node] : e=expression EOF { $node = (IBooleanNode)$e.ret; }; functionCaller returns [IBooleanNode node] : ID args=arguments { $node = new FuncNode($ID.text,$args.args);} ; arguments returns [List args] @init { $args = new ArrayList(); } : '(' expressionList[$args]? ')' ; expressionList[List args] : e1=expression { args.add($e1.ret); } (',' e2=expression { args.add($e2.ret); })* ; expression returns [Object ret] : c=conditionalOrExpression { $ret = $c.node; } | p=primary { $ret = $p.id; } ; conditionalOrExpression returns [IBooleanNode node] @init { List<IBooleanNode> children = new ArrayList<IBooleanNode>(); } : c1=conditionalAndExpression { children.add($c1.node); } ( OR c2=conditionalAndExpression { children.add($c2.node); } )* { $node = new OrNode(children);} ; conditionalAndExpression returns [IBooleanNode node] @init { List<IBooleanNode> children = new ArrayList<IBooleanNode>(); } : c1=conditionalNotExpression { children.add($c1.node); }( AND c2=conditionalNotExpression { children.add($c2.node); } )* { $node = new AndNode(children);} ; conditionalNotExpression returns [IBooleanNode node] : NOT caller=functionCaller { $node = new NotNode($caller.node); } | caller=functionCaller { $node = $caller.node; } | NOT p=parExpression { $node = new NotNode($p.node); } | p=parExpression { $node = $p.node; } ; parExpression returns [IBooleanNode node] : '(' e=conditionalOrExpression ')' { $node=$e.node; } ; primary returns [Object id] : INT { $id = $INT.text; } | STRING { String str= $STRING.text; $id = str.replaceAll("'", ""); } ; /*------------------------------------------------------------------ * LEXER RULES *------------------------------------------------------------------*/ ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')* ; INT : '0'..'9'+ ; WS : ( ' ' | '/t' | '/r' | '/n' ) {skip();} ; STRING : '/'' ( ESC_SEQ | ~('//'|'/'') )* '/'' ; fragment HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ; fragment ESC_SEQ : '//' ('b'|'t'|'n'|'f'|'r'|'/"'|'/''|'//') | UNICODE_ESC | OCTAL_ESC ; fragment OCTAL_ESC : '//' ('0'..'3') ('0'..'7') ('0'..'7') | '//' ('0'..'7') ('0'..'7') | '//' ('0'..'7') ; fragment UNICODE_ESC : '//' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT ;

 

  • 编译:

>java -classpath .;antlr-3.2.jar org.antlr.Tool PowserCheck3.g

会生成两个java文件PowserCheck3Lexer.java、PowserCheck3Parser.java

 

  • 用法:

String s = "use('T',11)"; try { ANTLRInputStream input = new ANTLRInputStream(new StringBufferInputStream(s)); PowserCheck3Lexer lexer = new PowserCheck3Lexer(input); CommonTokenStream tokens = new CommonTokenStream(lexer); PowserCheck3Parser parser = new PowserCheck3Parser(tokens); //begin parsing at rule r IBooleanNode root = parser.prog(); } catch (Exception e) { e.printStackTrace(); }

 

 

 

你可能感兴趣的:(exception,object,String,header,hex,Parsing)