From d9bd4de8d99cdf51133a6b96c247071ffa77eab2 Mon Sep 17 00:00:00 2001 From: mariofusco Date: Mon, 14 Feb 2022 19:08:30 +0100 Subject: [PATCH] improve drl parser --- .../src/main/antlr4/org/drools/parser/DRL.g4 | 1023 ++++++++++++++++- .../org/drools/parser/DRLParserHelper.java | 2 +- .../org/drools/parser/DRLVisitorImpl.java | 64 +- .../java/org/drools/parser/DRLParserTest.java | 43 +- 4 files changed, 1085 insertions(+), 47 deletions(-) diff --git a/drools-drl/drools-drl10-parser/src/main/antlr4/org/drools/parser/DRL.g4 b/drools-drl/drools-drl10-parser/src/main/antlr4/org/drools/parser/DRL.g4 index e83e84dd5ff..6cc31c5e2bd 100644 --- a/drools-drl/drools-drl10-parser/src/main/antlr4/org/drools/parser/DRL.g4 +++ b/drools-drl/drools-drl10-parser/src/main/antlr4/org/drools/parser/DRL.g4 @@ -1,64 +1,1019 @@ grammar DRL; +@members { + public String normalizeString( String input ) { + if( input != null && (input.length() == 2 || input.length() >= 4) ) { + input = input.substring( 1, input.length() - 1 ); + input = input.replaceAll( "\'", "'" ); + input = input.replaceAll( "\"", "\\\"" ); + input = "\"" + input + "\""; + } + return input; + } +} + +///////////////// // KEYWORDS +///////////////// PACKAGE : 'package'; +UNIT : 'unit'; IMPORT : 'import'; +FUNCTION : 'function'; +STATIC : 'static'; +GLOBAL : 'global'; RULE : 'rule'; +QUERY : 'query'; +EXTENDS : 'extends'; +SUPER : 'super'; WHEN : 'when'; THEN : 'then'; END : 'end'; +///////////////// +// LEXER +///////////////// + +WS : [ \t\r\n\u000C\u00A0]+ -> skip ; + +fragment +EOL : + ( '\r' // Macintosh + | '\n' // Unix (the right way) + ) + ; + +FLOAT + : ('0'..'9')+ '.' ('0'..'9')* Exponent? FloatTypeSuffix? + | '.' ('0'..'9')+ Exponent? FloatTypeSuffix? + | ('0'..'9')+ Exponent FloatTypeSuffix? + | ('0'..'9')+ FloatTypeSuffix + ; + +fragment +Exponent : ('e'|'E') ('+'|'-')? ('0'..'9')+ ; + +fragment +FloatTypeSuffix : ('f'|'F'|'d'|'D'|'B') ; + +HEX : '0' ('x'|'X') HexDigit+ IntegerTypeSuffix? ; + +DECIMAL : ('0'..'9')+ IntegerTypeSuffix? ; + +fragment +IntegerTypeSuffix : ('l'|'L'|'I') ; + +STRING + : ('"' ( EscapeSequence | ~('\\'|'"') )* '"') + | ('\'' ( EscapeSequence | ~('\\'|'\'') )* '\'') { setText( normalizeString( getText() ) ); } + ; + + +TIME_INTERVAL + : (('0'..'9')+ 'd') (('0'..'9')+ 'h')?(('0'..'9')+ 'm')?(('0'..'9')+ 's')?(('0'..'9')+ 'ms'?)? + | (('0'..'9')+ 'h') (('0'..'9')+ 'm')?(('0'..'9')+ 's')?(('0'..'9')+ 'ms'?)? + | (('0'..'9')+ 'm') (('0'..'9')+ 's')?(('0'..'9')+ 'ms'?)? + | (('0'..'9')+ 's') (('0'..'9')+ 'ms'?)? + | (('0'..'9')+ 'ms'?) + ; + +fragment +HexDigit : ('0'..'9'|'a'..'f'|'A'..'F') ; + +fragment +EscapeSequence + : '\\' ('b'|'B'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\'|'.'|'o'| + 'x'|'a'|'e'|'c'|'d'|'D'|'s'|'S'|'w'|'W'|'p'|'A'| + 'G'|'Z'|'z'|'Q'|'E'|'*'|'['|']'|'('|')'|'$'|'^'| + '{'|'}'|'?'|'+'|'-'|'&'|'|') + | UnicodeEscape + | OctalEscape + ; + +fragment +OctalEscape + : '\\' ('0'..'3') ('0'..'7') ('0'..'7') + | '\\' ('0'..'7') ('0'..'7') + | '\\' ('0'..'7') + ; + +fragment +UnicodeEscape + : '\\' 'u' HexDigit HexDigit HexDigit HexDigit + ; + +///////////////// +// SYMBOLS +///////////////// + +BOOL : ('true'|'false') ; +NULL : 'null' ; +AT : '@' ; +PLUS_ASSIGN : '+=' ; +MINUS_ASSIGN : '-=' ; +MULT_ASSIGN : '*=' ; +DIV_ASSIGN : '/=' ; +AND_ASSIGN : '&=' ; +OR_ASSIGN : '|=' ; +XOR_ASSIGN : '^=' ; +MOD_ASSIGN : '%=' ; +UNIFY : ':=' ; +DECR : '--' ; +INCR : '++' ; +ARROW : '->' ; +SEMICOLON : ';' ; +COLON : ':' ; +EQUALS : '==' ; +NOT_EQUALS : '!=' ; +GREATER_EQUALS : '>=' ; +LESS_EQUALS : '<=' ; +GREATER : '>' ; +LESS : '<' ; +EQUALS_ASSIGN : '=' ; +LEFT_PAREN : '(' ; +RIGHT_PAREN : ')' ; + +LEFT_SQUARE + : '[' + ; + +RIGHT_SQUARE + : ']' + ; + +LEFT_CURLY + : '{' + ; + +RIGHT_CURLY + : '}' + ; + +COMMA : ',' + ; + +DOT : '.' + ; + +NULL_SAFE_DOT : '!.' + ; + +DOUBLE_AMPER + : '&&' + ; + +DOUBLE_PIPE + : '||' + ; + +QUESTION + : '?' + ; + +NEGATION + : '!' + ; + +TILDE + : '~' + ; + +PIPE + : '|' + ; + +AMPER + : '&' + ; + +XOR + : '^' + ; + +MOD + : '%' + ; + +STAR : '*' + ; + +MINUS : '-' + ; + +PLUS : '+' + ; + +HASH : '#' + ; + +C_STYLE_SINGLE_LINE_COMMENT + : '//' (~('\r'|'\n'))* (EOL|EOF) -> skip + ; + +MULTI_LINE_COMMENT + : '/*' (options{greedy=false;} : .)* '*/' -> skip + ; + +ID + : IdentifierStart IdentifierPart* + | '`' IdentifierStart IdentifierPart* '`' + ; + +// must come after the commentaries that use 2-character sequences with / +DIV : '/' + ; + +QUESTION_DIV + : '?/' + ; + +MISC : + '\'' | '\\' | '$' + ; + +fragment +IdentifierStart + : '\u0024' + | '\u0041'..'\u005a' + | '\u005f' + | '\u0061'..'\u007a' + | '\u00a2'..'\u00a5' + | '\u00aa' + | '\u00b5' + | '\u00ba' + | '\u00c0'..'\u00d6' + | '\u00d8'..'\u00f6' + | '\u00f8'..'\u0236' + | '\u0250'..'\u02c1' + | '\u02c6'..'\u02d1' + | '\u02e0'..'\u02e4' + | '\u02ee' + | '\u037a' + | '\u0386' + | '\u0388'..'\u038a' + | '\u038c' + | '\u038e'..'\u03a1' + | '\u03a3'..'\u03ce' + | '\u03d0'..'\u03f5' + | '\u03f7'..'\u03fb' + | '\u0400'..'\u0481' + | '\u048a'..'\u04ce' + | '\u04d0'..'\u04f5' + | '\u04f8'..'\u04f9' + | '\u0500'..'\u050f' + | '\u0531'..'\u0556' + | '\u0559' + | '\u0561'..'\u0587' + | '\u05d0'..'\u05ea' + | '\u05f0'..'\u05f2' + | '\u0621'..'\u063a' + | '\u0640'..'\u064a' + | '\u066e'..'\u066f' + | '\u0671'..'\u06d3' + | '\u06d5' + | '\u06e5'..'\u06e6' + | '\u06ee'..'\u06ef' + | '\u06fa'..'\u06fc' + | '\u06ff' + | '\u0710' + | '\u0712'..'\u072f' + | '\u074d'..'\u074f' + | '\u0780'..'\u07a5' + | '\u07b1' + | '\u0904'..'\u0939' + | '\u093d' + | '\u0950' + | '\u0958'..'\u0961' + | '\u0985'..'\u098c' + | '\u098f'..'\u0990' + | '\u0993'..'\u09a8' + | '\u09aa'..'\u09b0' + | '\u09b2' + | '\u09b6'..'\u09b9' + | '\u09bd' + | '\u09dc'..'\u09dd' + | '\u09df'..'\u09e1' + | '\u09f0'..'\u09f3' + | '\u0a05'..'\u0a0a' + | '\u0a0f'..'\u0a10' + | '\u0a13'..'\u0a28' + | '\u0a2a'..'\u0a30' + | '\u0a32'..'\u0a33' + | '\u0a35'..'\u0a36' + | '\u0a38'..'\u0a39' + | '\u0a59'..'\u0a5c' + | '\u0a5e' + | '\u0a72'..'\u0a74' + | '\u0a85'..'\u0a8d' + | '\u0a8f'..'\u0a91' + | '\u0a93'..'\u0aa8' + | '\u0aaa'..'\u0ab0' + | '\u0ab2'..'\u0ab3' + | '\u0ab5'..'\u0ab9' + | '\u0abd' + | '\u0ad0' + | '\u0ae0'..'\u0ae1' + | '\u0af1' + | '\u0b05'..'\u0b0c' + | '\u0b0f'..'\u0b10' + | '\u0b13'..'\u0b28' + | '\u0b2a'..'\u0b30' + | '\u0b32'..'\u0b33' + | '\u0b35'..'\u0b39' + | '\u0b3d' + | '\u0b5c'..'\u0b5d' + | '\u0b5f'..'\u0b61' + | '\u0b71' + | '\u0b83' + | '\u0b85'..'\u0b8a' + | '\u0b8e'..'\u0b90' + | '\u0b92'..'\u0b95' + | '\u0b99'..'\u0b9a' + | '\u0b9c' + | '\u0b9e'..'\u0b9f' + | '\u0ba3'..'\u0ba4' + | '\u0ba8'..'\u0baa' + | '\u0bae'..'\u0bb5' + | '\u0bb7'..'\u0bb9' + | '\u0bf9' + | '\u0c05'..'\u0c0c' + | '\u0c0e'..'\u0c10' + | '\u0c12'..'\u0c28' + | '\u0c2a'..'\u0c33' + | '\u0c35'..'\u0c39' + | '\u0c60'..'\u0c61' + | '\u0c85'..'\u0c8c' + | '\u0c8e'..'\u0c90' + | '\u0c92'..'\u0ca8' + | '\u0caa'..'\u0cb3' + | '\u0cb5'..'\u0cb9' + | '\u0cbd' + | '\u0cde' + | '\u0ce0'..'\u0ce1' + | '\u0d05'..'\u0d0c' + | '\u0d0e'..'\u0d10' + | '\u0d12'..'\u0d28' + | '\u0d2a'..'\u0d39' + | '\u0d60'..'\u0d61' + | '\u0d85'..'\u0d96' + | '\u0d9a'..'\u0db1' + | '\u0db3'..'\u0dbb' + | '\u0dbd' + | '\u0dc0'..'\u0dc6' + | '\u0e01'..'\u0e30' + | '\u0e32'..'\u0e33' + | '\u0e3f'..'\u0e46' + | '\u0e81'..'\u0e82' + | '\u0e84' + | '\u0e87'..'\u0e88' + | '\u0e8a' + | '\u0e8d' + | '\u0e94'..'\u0e97' + | '\u0e99'..'\u0e9f' + | '\u0ea1'..'\u0ea3' + | '\u0ea5' + | '\u0ea7' + | '\u0eaa'..'\u0eab' + | '\u0ead'..'\u0eb0' + | '\u0eb2'..'\u0eb3' + | '\u0ebd' + | '\u0ec0'..'\u0ec4' + | '\u0ec6' + | '\u0edc'..'\u0edd' + | '\u0f00' + | '\u0f40'..'\u0f47' + | '\u0f49'..'\u0f6a' + | '\u0f88'..'\u0f8b' + | '\u1000'..'\u1021' + | '\u1023'..'\u1027' + | '\u1029'..'\u102a' + | '\u1050'..'\u1055' + | '\u10a0'..'\u10c5' + | '\u10d0'..'\u10f8' + | '\u1100'..'\u1159' + | '\u115f'..'\u11a2' + | '\u11a8'..'\u11f9' + | '\u1200'..'\u1206' + | '\u1208'..'\u1246' + | '\u1248' + | '\u124a'..'\u124d' + | '\u1250'..'\u1256' + | '\u1258' + | '\u125a'..'\u125d' + | '\u1260'..'\u1286' + | '\u1288' + | '\u128a'..'\u128d' + | '\u1290'..'\u12ae' + | '\u12b0' + | '\u12b2'..'\u12b5' + | '\u12b8'..'\u12be' + | '\u12c0' + | '\u12c2'..'\u12c5' + | '\u12c8'..'\u12ce' + | '\u12d0'..'\u12d6' + | '\u12d8'..'\u12ee' + | '\u12f0'..'\u130e' + | '\u1310' + | '\u1312'..'\u1315' + | '\u1318'..'\u131e' + | '\u1320'..'\u1346' + | '\u1348'..'\u135a' + | '\u13a0'..'\u13f4' + | '\u1401'..'\u166c' + | '\u166f'..'\u1676' + | '\u1681'..'\u169a' + | '\u16a0'..'\u16ea' + | '\u16ee'..'\u16f0' + | '\u1700'..'\u170c' + | '\u170e'..'\u1711' + | '\u1720'..'\u1731' + | '\u1740'..'\u1751' + | '\u1760'..'\u176c' + | '\u176e'..'\u1770' + | '\u1780'..'\u17b3' + | '\u17d7' + | '\u17db'..'\u17dc' + | '\u1820'..'\u1877' + | '\u1880'..'\u18a8' + | '\u1900'..'\u191c' + | '\u1950'..'\u196d' + | '\u1970'..'\u1974' + | '\u1d00'..'\u1d6b' + | '\u1e00'..'\u1e9b' + | '\u1ea0'..'\u1ef9' + | '\u1f00'..'\u1f15' + | '\u1f18'..'\u1f1d' + | '\u1f20'..'\u1f45' + | '\u1f48'..'\u1f4d' + | '\u1f50'..'\u1f57' + | '\u1f59' + | '\u1f5b' + | '\u1f5d' + | '\u1f5f'..'\u1f7d' + | '\u1f80'..'\u1fb4' + | '\u1fb6'..'\u1fbc' + | '\u1fbe' + | '\u1fc2'..'\u1fc4' + | '\u1fc6'..'\u1fcc' + | '\u1fd0'..'\u1fd3' + | '\u1fd6'..'\u1fdb' + | '\u1fe0'..'\u1fec' + | '\u1ff2'..'\u1ff4' + | '\u1ff6'..'\u1ffc' + | '\u203f'..'\u2040' + | '\u2054' + | '\u2071' + | '\u207f' + | '\u20a0'..'\u20b1' + | '\u2102' + | '\u2107' + | '\u210a'..'\u2113' + | '\u2115' + | '\u2119'..'\u211d' + | '\u2124' + | '\u2126' + | '\u2128' + | '\u212a'..'\u212d' + | '\u212f'..'\u2131' + | '\u2133'..'\u2139' + | '\u213d'..'\u213f' + | '\u2145'..'\u2149' + | '\u2160'..'\u2183' + | '\u3005'..'\u3007' + | '\u3021'..'\u3029' + | '\u3031'..'\u3035' + | '\u3038'..'\u303c' + | '\u3041'..'\u3096' + | '\u309d'..'\u309f' + | '\u30a1'..'\u30ff' + | '\u3105'..'\u312c' + | '\u3131'..'\u318e' + | '\u31a0'..'\u31b7' + | '\u31f0'..'\u31ff' + | '\u3400'..'\u4db5' + | '\u4e00'..'\u9fa5' + | '\ua000'..'\ua48c' + | '\uac00'..'\ud7a3' + | '\uf900'..'\ufa2d' + | '\ufa30'..'\ufa6a' + | '\ufb00'..'\ufb06' + | '\ufb13'..'\ufb17' + | '\ufb1d' + | '\ufb1f'..'\ufb28' + | '\ufb2a'..'\ufb36' + | '\ufb38'..'\ufb3c' + | '\ufb3e' + | '\ufb40'..'\ufb41' + | '\ufb43'..'\ufb44' + | '\ufb46'..'\ufbb1' + | '\ufbd3'..'\ufd3d' + | '\ufd50'..'\ufd8f' + | '\ufd92'..'\ufdc7' + | '\ufdf0'..'\ufdfc' + | '\ufe33'..'\ufe34' + | '\ufe4d'..'\ufe4f' + | '\ufe69' + | '\ufe70'..'\ufe74' + | '\ufe76'..'\ufefc' + | '\uff04' + | '\uff21'..'\uff3a' + | '\uff3f' + | '\uff41'..'\uff5a' + | '\uff65'..'\uffbe' + | '\uffc2'..'\uffc7' + | '\uffca'..'\uffcf' + | '\uffd2'..'\uffd7' + | '\uffda'..'\uffdc' + | '\uffe0'..'\uffe1' + | '\uffe5'..'\uffe6' +// UTF-16: | ('\ud800'..'\udbff') ('\udc00'..'\udfff') + ; + +fragment +IdentifierPart + : '\u0000'..'\u0008' + | '\u000e'..'\u001b' + | '\u0024' + | '\u0030'..'\u0039' + | '\u0041'..'\u005a' + | '\u005f' + | '\u0061'..'\u007a' + | '\u007f'..'\u009f' + | '\u00a2'..'\u00a5' + | '\u00aa' + | '\u00ad' + | '\u00b5' + | '\u00ba' + | '\u00c0'..'\u00d6' + | '\u00d8'..'\u00f6' + | '\u00f8'..'\u0236' + | '\u0250'..'\u02c1' + | '\u02c6'..'\u02d1' + | '\u02e0'..'\u02e4' + | '\u02ee' + | '\u0300'..'\u0357' + | '\u035d'..'\u036f' + | '\u037a' + | '\u0386' + | '\u0388'..'\u038a' + | '\u038c' + | '\u038e'..'\u03a1' + | '\u03a3'..'\u03ce' + | '\u03d0'..'\u03f5' + | '\u03f7'..'\u03fb' + | '\u0400'..'\u0481' + | '\u0483'..'\u0486' + | '\u048a'..'\u04ce' + | '\u04d0'..'\u04f5' + | '\u04f8'..'\u04f9' + | '\u0500'..'\u050f' + | '\u0531'..'\u0556' + | '\u0559' + | '\u0561'..'\u0587' + | '\u0591'..'\u05a1' + | '\u05a3'..'\u05b9' + | '\u05bb'..'\u05bd' + | '\u05bf' + | '\u05c1'..'\u05c2' + | '\u05c4' + | '\u05d0'..'\u05ea' + | '\u05f0'..'\u05f2' + | '\u0600'..'\u0603' + | '\u0610'..'\u0615' + | '\u0621'..'\u063a' + | '\u0640'..'\u0658' + | '\u0660'..'\u0669' + | '\u066e'..'\u06d3' + | '\u06d5'..'\u06dd' + | '\u06df'..'\u06e8' + | '\u06ea'..'\u06fc' + | '\u06ff' + | '\u070f'..'\u074a' + | '\u074d'..'\u074f' + | '\u0780'..'\u07b1' + | '\u0901'..'\u0939' + | '\u093c'..'\u094d' + | '\u0950'..'\u0954' + | '\u0958'..'\u0963' + | '\u0966'..'\u096f' + | '\u0981'..'\u0983' + | '\u0985'..'\u098c' + | '\u098f'..'\u0990' + | '\u0993'..'\u09a8' + | '\u09aa'..'\u09b0' + | '\u09b2' + | '\u09b6'..'\u09b9' + | '\u09bc'..'\u09c4' + | '\u09c7'..'\u09c8' + | '\u09cb'..'\u09cd' + | '\u09d7' + | '\u09dc'..'\u09dd' + | '\u09df'..'\u09e3' + | '\u09e6'..'\u09f3' + | '\u0a01'..'\u0a03' + | '\u0a05'..'\u0a0a' + | '\u0a0f'..'\u0a10' + | '\u0a13'..'\u0a28' + | '\u0a2a'..'\u0a30' + | '\u0a32'..'\u0a33' + | '\u0a35'..'\u0a36' + | '\u0a38'..'\u0a39' + | '\u0a3c' + | '\u0a3e'..'\u0a42' + | '\u0a47'..'\u0a48' + | '\u0a4b'..'\u0a4d' + | '\u0a59'..'\u0a5c' + | '\u0a5e' + | '\u0a66'..'\u0a74' + | '\u0a81'..'\u0a83' + | '\u0a85'..'\u0a8d' + | '\u0a8f'..'\u0a91' + | '\u0a93'..'\u0aa8' + | '\u0aaa'..'\u0ab0' + | '\u0ab2'..'\u0ab3' + | '\u0ab5'..'\u0ab9' + | '\u0abc'..'\u0ac5' + | '\u0ac7'..'\u0ac9' + | '\u0acb'..'\u0acd' + | '\u0ad0' + | '\u0ae0'..'\u0ae3' + | '\u0ae6'..'\u0aef' + | '\u0af1' + | '\u0b01'..'\u0b03' + | '\u0b05'..'\u0b0c' + | '\u0b0f'..'\u0b10' + | '\u0b13'..'\u0b28' + | '\u0b2a'..'\u0b30' + | '\u0b32'..'\u0b33' + | '\u0b35'..'\u0b39' + | '\u0b3c'..'\u0b43' + | '\u0b47'..'\u0b48' + | '\u0b4b'..'\u0b4d' + | '\u0b56'..'\u0b57' + | '\u0b5c'..'\u0b5d' + | '\u0b5f'..'\u0b61' + | '\u0b66'..'\u0b6f' + | '\u0b71' + | '\u0b82'..'\u0b83' + | '\u0b85'..'\u0b8a' + | '\u0b8e'..'\u0b90' + | '\u0b92'..'\u0b95' + | '\u0b99'..'\u0b9a' + | '\u0b9c' + | '\u0b9e'..'\u0b9f' + | '\u0ba3'..'\u0ba4' + | '\u0ba8'..'\u0baa' + | '\u0bae'..'\u0bb5' + | '\u0bb7'..'\u0bb9' + | '\u0bbe'..'\u0bc2' + | '\u0bc6'..'\u0bc8' + | '\u0bca'..'\u0bcd' + | '\u0bd7' + | '\u0be7'..'\u0bef' + | '\u0bf9' + | '\u0c01'..'\u0c03' + | '\u0c05'..'\u0c0c' + | '\u0c0e'..'\u0c10' + | '\u0c12'..'\u0c28' + | '\u0c2a'..'\u0c33' + | '\u0c35'..'\u0c39' + | '\u0c3e'..'\u0c44' + | '\u0c46'..'\u0c48' + | '\u0c4a'..'\u0c4d' + | '\u0c55'..'\u0c56' + | '\u0c60'..'\u0c61' + | '\u0c66'..'\u0c6f' + | '\u0c82'..'\u0c83' + | '\u0c85'..'\u0c8c' + | '\u0c8e'..'\u0c90' + | '\u0c92'..'\u0ca8' + | '\u0caa'..'\u0cb3' + | '\u0cb5'..'\u0cb9' + | '\u0cbc'..'\u0cc4' + | '\u0cc6'..'\u0cc8' + | '\u0cca'..'\u0ccd' + | '\u0cd5'..'\u0cd6' + | '\u0cde' + | '\u0ce0'..'\u0ce1' + | '\u0ce6'..'\u0cef' + | '\u0d02'..'\u0d03' + | '\u0d05'..'\u0d0c' + | '\u0d0e'..'\u0d10' + | '\u0d12'..'\u0d28' + | '\u0d2a'..'\u0d39' + | '\u0d3e'..'\u0d43' + | '\u0d46'..'\u0d48' + | '\u0d4a'..'\u0d4d' + | '\u0d57' + | '\u0d60'..'\u0d61' + | '\u0d66'..'\u0d6f' + | '\u0d82'..'\u0d83' + | '\u0d85'..'\u0d96' + | '\u0d9a'..'\u0db1' + | '\u0db3'..'\u0dbb' + | '\u0dbd' + | '\u0dc0'..'\u0dc6' + | '\u0dca' + | '\u0dcf'..'\u0dd4' + | '\u0dd6' + | '\u0dd8'..'\u0ddf' + | '\u0df2'..'\u0df3' + | '\u0e01'..'\u0e3a' + | '\u0e3f'..'\u0e4e' + | '\u0e50'..'\u0e59' + | '\u0e81'..'\u0e82' + | '\u0e84' + | '\u0e87'..'\u0e88' + | '\u0e8a' + | '\u0e8d' + | '\u0e94'..'\u0e97' + | '\u0e99'..'\u0e9f' + | '\u0ea1'..'\u0ea3' + | '\u0ea5' + | '\u0ea7' + | '\u0eaa'..'\u0eab' + | '\u0ead'..'\u0eb9' + | '\u0ebb'..'\u0ebd' + | '\u0ec0'..'\u0ec4' + | '\u0ec6' + | '\u0ec8'..'\u0ecd' + | '\u0ed0'..'\u0ed9' + | '\u0edc'..'\u0edd' + | '\u0f00' + | '\u0f18'..'\u0f19' + | '\u0f20'..'\u0f29' + | '\u0f35' + | '\u0f37' + | '\u0f39' + | '\u0f3e'..'\u0f47' + | '\u0f49'..'\u0f6a' + | '\u0f71'..'\u0f84' + | '\u0f86'..'\u0f8b' + | '\u0f90'..'\u0f97' + | '\u0f99'..'\u0fbc' + | '\u0fc6' + | '\u1000'..'\u1021' + | '\u1023'..'\u1027' + | '\u1029'..'\u102a' + | '\u102c'..'\u1032' + | '\u1036'..'\u1039' + | '\u1040'..'\u1049' + | '\u1050'..'\u1059' + | '\u10a0'..'\u10c5' + | '\u10d0'..'\u10f8' + | '\u1100'..'\u1159' + | '\u115f'..'\u11a2' + | '\u11a8'..'\u11f9' + | '\u1200'..'\u1206' + | '\u1208'..'\u1246' + | '\u1248' + | '\u124a'..'\u124d' + | '\u1250'..'\u1256' + | '\u1258' + | '\u125a'..'\u125d' + | '\u1260'..'\u1286' + | '\u1288' + | '\u128a'..'\u128d' + | '\u1290'..'\u12ae' + | '\u12b0' + | '\u12b2'..'\u12b5' + | '\u12b8'..'\u12be' + | '\u12c0' + | '\u12c2'..'\u12c5' + | '\u12c8'..'\u12ce' + | '\u12d0'..'\u12d6' + | '\u12d8'..'\u12ee' + | '\u12f0'..'\u130e' + | '\u1310' + | '\u1312'..'\u1315' + | '\u1318'..'\u131e' + | '\u1320'..'\u1346' + | '\u1348'..'\u135a' + | '\u1369'..'\u1371' + | '\u13a0'..'\u13f4' + | '\u1401'..'\u166c' + | '\u166f'..'\u1676' + | '\u1681'..'\u169a' + | '\u16a0'..'\u16ea' + | '\u16ee'..'\u16f0' + | '\u1700'..'\u170c' + | '\u170e'..'\u1714' + | '\u1720'..'\u1734' + | '\u1740'..'\u1753' + | '\u1760'..'\u176c' + | '\u176e'..'\u1770' + | '\u1772'..'\u1773' + | '\u1780'..'\u17d3' + | '\u17d7' + | '\u17db'..'\u17dd' + | '\u17e0'..'\u17e9' + | '\u180b'..'\u180d' + | '\u1810'..'\u1819' + | '\u1820'..'\u1877' + | '\u1880'..'\u18a9' + | '\u1900'..'\u191c' + | '\u1920'..'\u192b' + | '\u1930'..'\u193b' + | '\u1946'..'\u196d' + | '\u1970'..'\u1974' + | '\u1d00'..'\u1d6b' + | '\u1e00'..'\u1e9b' + | '\u1ea0'..'\u1ef9' + | '\u1f00'..'\u1f15' + | '\u1f18'..'\u1f1d' + | '\u1f20'..'\u1f45' + | '\u1f48'..'\u1f4d' + | '\u1f50'..'\u1f57' + | '\u1f59' + | '\u1f5b' + | '\u1f5d' + | '\u1f5f'..'\u1f7d' + | '\u1f80'..'\u1fb4' + | '\u1fb6'..'\u1fbc' + | '\u1fbe' + | '\u1fc2'..'\u1fc4' + | '\u1fc6'..'\u1fcc' + | '\u1fd0'..'\u1fd3' + | '\u1fd6'..'\u1fdb' + | '\u1fe0'..'\u1fec' + | '\u1ff2'..'\u1ff4' + | '\u1ff6'..'\u1ffc' + | '\u200c'..'\u200f' + | '\u202a'..'\u202e' + | '\u203f'..'\u2040' + | '\u2054' + | '\u2060'..'\u2063' + | '\u206a'..'\u206f' + | '\u2071' + | '\u207f' + | '\u20a0'..'\u20b1' + | '\u20d0'..'\u20dc' + | '\u20e1' + | '\u20e5'..'\u20ea' + | '\u2102' + | '\u2107' + | '\u210a'..'\u2113' + | '\u2115' + | '\u2119'..'\u211d' + | '\u2124' + | '\u2126' + | '\u2128' + | '\u212a'..'\u212d' + | '\u212f'..'\u2131' + | '\u2133'..'\u2139' + | '\u213d'..'\u213f' + | '\u2145'..'\u2149' + | '\u2160'..'\u2183' + | '\u3005'..'\u3007' + | '\u3021'..'\u302f' + | '\u3031'..'\u3035' + | '\u3038'..'\u303c' + | '\u3041'..'\u3096' + | '\u3099'..'\u309a' + | '\u309d'..'\u309f' + | '\u30a1'..'\u30ff' + | '\u3105'..'\u312c' + | '\u3131'..'\u318e' + | '\u31a0'..'\u31b7' + | '\u31f0'..'\u31ff' + | '\u3400'..'\u4db5' + | '\u4e00'..'\u9fa5' + | '\ua000'..'\ua48c' + | '\uac00'..'\ud7a3' + | '\uf900'..'\ufa2d' + | '\ufa30'..'\ufa6a' + | '\ufb00'..'\ufb06' + | '\ufb13'..'\ufb17' + | '\ufb1d'..'\ufb28' + | '\ufb2a'..'\ufb36' + | '\ufb38'..'\ufb3c' + | '\ufb3e' + | '\ufb40'..'\ufb41' + | '\ufb43'..'\ufb44' + | '\ufb46'..'\ufbb1' + | '\ufbd3'..'\ufd3d' + | '\ufd50'..'\ufd8f' + | '\ufd92'..'\ufdc7' + | '\ufdf0'..'\ufdfc' + | '\ufe00'..'\ufe0f' + | '\ufe20'..'\ufe23' + | '\ufe33'..'\ufe34' + | '\ufe4d'..'\ufe4f' + | '\ufe69' + | '\ufe70'..'\ufe74' + | '\ufe76'..'\ufefc' + | '\ufeff' + | '\uff04' + | '\uff10'..'\uff19' + | '\uff21'..'\uff3a' + | '\uff3f' + | '\uff41'..'\uff5a' + | '\uff65'..'\uffbe' + | '\uffc2'..'\uffc7' + | '\uffca'..'\uffcf' + | '\uffd2'..'\uffd7' + | '\uffda'..'\uffdc' + | '\uffe0'..'\uffe1' + | '\uffe5'..'\uffe6' + | '\ufff9'..'\ufffb' +// UTF-16 | ('\ud800'..'\udbff') ('\udc00'..'\udfff') + ; + +///////////////// // PARSER +///////////////// + +compilationunit : packagedef? unitdef? importdef* globaldef* ruledef* ; -compilationunit : packagedef? importdef* ruledef* ; +packagedef : PACKAGE name=qualifiedIdentifier SEMICOLON? ; -packagedef : PACKAGE FQNAME SEMICOLON? ; +unitdef : UNIT name=qualifiedIdentifier SEMICOLON? ; -importdef : IMPORT FQNAME (DOT STAR)? SEMICOLON? ; +importdef : IMPORT (FUNCTION|STATIC)? qualifiedIdentifier (DOT STAR)? SEMICOLON? ; -ruledef : RULE IDENTIFIER WHEN lhs THEN rhs END ; +globaldef : GLOBAL type ID SEMICOLON? ; -lhs : TEXT ; +ruledef : RULE name=stringId (EXTENDS stringId)? annotation* attributes? WHEN lhs THEN rhs END ; + +lhs : lhsExpression ; +lhsExpression : lhsOr* ; +lhsOr : LEFT_PAREN OR lhsAnd+ RIGHT_PAREN | lhsAnd (OR lhsAnd)* ; +lhsAnd : LEFT_PAREN AND lhsUnary+ RIGHT_PAREN | lhsUnary (AND lhsUnary)* ; + +/* +lhsUnary : ( lhsExists namedConsequence? + | lhsNot namedConsequence? + | lhsEval consequenceInvocation* + | lhsForall + | lhsAccumulate + | LEFT_PAREN lhsOr RIGHT_PAREN namedConsequence? + | lhsPatternBind consequenceInvocation* + ) SEMICOLON? ; +*/ + +lhsUnary : lhsPatternBind ; +lhsPatternBind : label? ( LEFT_PAREN lhsPattern (OR lhsPattern)* RIGHT_PAREN | lhsPattern ) ; + +/* +lhsPattern : xpathPrimary (OVER patternFilter)? | + ( QUESTION? qualifiedIdentifier LEFT_PAREN positionalConstraints? constraints? RIGHT_PAREN (OVER patternFilter)? (FROM patternSource)? ) ; +*/ + +lhsPattern : QUESTION? objectType=qualifiedIdentifier LEFT_PAREN positionalConstraints? constraints? RIGHT_PAREN ; +positionalConstraints : constraint (COMMA constraint)* SEMICOLON ; +constraints : constraint (COMMA constraint)* ; +constraint : nestedConstraint | conditionalOrExpression ; +nestedConstraint : ( ID ( DOT | HASH ) )* ID DOT LEFT_PAREN constraints RIGHT_PAREN ; +conditionalOrExpression : left=conditionalAndExpression (DOUBLE_PIPE right=conditionalAndExpression)* ; +conditionalAndExpression : left=inclusiveOrExpression (DOUBLE_AMPER right=inclusiveOrExpression)* ; +inclusiveOrExpression : left=exclusiveOrExpression (PIPE right=exclusiveOrExpression)* ; +exclusiveOrExpression : left=andExpression (XOR right=andExpression)* ; +andExpression : left=equalityExpression (AMPER right=equalityExpression)* ; +equalityExpression : left=instanceOfExpression ( ( op=EQUALS | op=NOT_EQUALS ) right=instanceOfExpression )* ; +instanceOfExpression : left=inExpression ( 'instanceof' right=type )? ; +inExpression : left=relationalExpression ( 'not'? 'in' LEFT_PAREN expression (COMMA expression)* RIGHT_PAREN )? ; +relationalExpression : TEXT? ; // TODO + +expression : conditionalExpression ( op=assignmentOperator right=expression )? ; +conditionalExpression : left=conditionalOrExpression ternaryExpression? ; +ternaryExpression : QUESTION ts=expression COLON fs=expression ; rhs : TEXT ; -// LITERALS +stringId : ( ID | STRING ) ; -fragment DIGIT : [0-9] ; -NUMBER : DIGIT+ ([.,] DIGIT+)? ; +qualifiedIdentifier : ID ( DOT ID )* ; -fragment LOWERCASE : [a-z] ; -fragment UPPERCASE : [A-Z] ; -LETTER : (LOWERCASE | UPPERCASE | '_' | '$') ; +type : ID typeArguments? ( DOT ID typeArguments? )* (LEFT_SQUARE RIGHT_SQUARE)* ; -IDENTIFIER : LETTER (LETTER | DIGIT)* ; -FQNAME : IDENTIFIER (DOT IDENTIFIER)* ; +typeArguments : LESS typeArgument (COMMA typeArgument)* GREATER ; +typeArgument : QUESTION (( EXTENDS | SUPER ) type )? | type ; -// SEPARATORS +arguments : LEFT_PAREN argument (COMMA argument)* RIGHT_PAREN ; +argument : ( stringId | FLOAT | BOOL | NULL ) ; -LPAREN : '('; -RPAREN : ')'; -LBRACE : '{'; -RBRACE : '}'; -LBRACK : '['; -RBRACK : ']'; -COMMA : ','; -ELIPSIS : '..'; -DOT : '.'; -COLON : ':'; -SEMICOLON : ';'; -STAR : '*'; +annotation : AT name=qualifiedIdentifier arguments? ; -// OPERATORS +attributes : attribute ( COMMA? attribute )* ; +attribute : ( 'salience' DECIMAL ) + | ( 'enabled' | 'no-loop' | 'auto-focus' | 'lock-on-active' | 'refract' | 'direct' ) BOOLEAN? + | ( 'agenda-group' | 'activation-group' | 'ruleflow-group' | 'date-effective' | 'date-expires' | 'dialect' ) STRING + | 'calendars' STRING ( COMMA STRING )* + | 'timer' ( DECIMAL | TEXT ) + | 'duration' ( DECIMAL | TEXT ) ; -EQUAL : '='; -GT : '>'; -LT : '<'; -LE : '<='; -GE : '>='; -NOTEQUAL : '!='; +assignmentOperator : EQUALS_ASSIGN + | PLUS_ASSIGN + | MINUS_ASSIGN + | MULT_ASSIGN + | DIV_ASSIGN + | AND_ASSIGN + | OR_ASSIGN + | XOR_ASSIGN + | MOD_ASSIGN + | LESS LESS EQUALS_ASSIGN ; -WS : [ \t\r\n\u000C\u00A0]+ -> skip ; +label : ID COLON ; +unif : ID UNIFY ; fragment TEXT : .+ ; diff --git a/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLParserHelper.java b/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLParserHelper.java index f036bc90d62..f1c254fa332 100644 --- a/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLParserHelper.java +++ b/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLParserHelper.java @@ -118,6 +118,6 @@ public static int getNodeIndex(ParseTree node) { if (node instanceof TerminalNode) { return ((TerminalNode) node).getSymbol().getTokenIndex(); } - return node.getChildCount() == 0 ? 0: getNodeIndex(node.getChild(node.getChildCount()-1)); + return node.getChildCount() == 0 ? 0: getNodeIndex(node.getChild(0)); } } diff --git a/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLVisitorImpl.java b/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLVisitorImpl.java index 780076b9ab5..9aa2fbce870 100644 --- a/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLVisitorImpl.java +++ b/drools-drl/drools-drl10-parser/src/main/java/org/drools/parser/DRLVisitorImpl.java @@ -1,13 +1,20 @@ package org.drools.parser; +import org.drools.drl.ast.descr.AnnotationDescr; +import org.drools.drl.ast.descr.AttributeDescr; +import org.drools.drl.ast.descr.GlobalDescr; import org.drools.drl.ast.descr.ImportDescr; import org.drools.drl.ast.descr.PackageDescr; +import org.drools.drl.ast.descr.PatternDescr; import org.drools.drl.ast.descr.RuleDescr; +import org.drools.drl.ast.descr.UnitDescr; public class DRLVisitorImpl extends DRLBaseVisitor { private final PackageDescr packageDescr = new PackageDescr(); + private RuleDescr ruleDescr; + @Override public Object visitCompilationunit(DRLParser.CompilationunitContext ctx) { return super.visitCompilationunit(ctx); @@ -15,23 +22,68 @@ public Object visitCompilationunit(DRLParser.CompilationunitContext ctx) { @Override public Object visitPackagedef(DRLParser.PackagedefContext ctx) { - packageDescr.setName(ctx.FQNAME().getText()); + packageDescr.setName(ctx.name.getText()); return super.visitPackagedef(ctx); } + @Override + public Object visitUnitdef(DRLParser.UnitdefContext ctx) { + packageDescr.setUnit(new UnitDescr(ctx.name.getText())); + return super.visitUnitdef(ctx); + } + + @Override + public Object visitGlobaldef(DRLParser.GlobaldefContext ctx) { + packageDescr.addGlobal(new GlobalDescr(ctx.ID().getText(), ctx.type().getText())); + return super.visitGlobaldef(ctx); + } + @Override public Object visitImportdef(DRLParser.ImportdefContext ctx) { - String imp = ctx.FQNAME().getText() + (ctx.STAR() != null ? ".*" : ""); + String imp = ctx.qualifiedIdentifier().getText() + (ctx.STAR() != null ? ".*" : ""); packageDescr.addImport(new ImportDescr(imp)); return super.visitImportdef(ctx); } @Override public Object visitRuledef(DRLParser.RuledefContext ctx) { - RuleDescr rule = new RuleDescr(ctx.IDENTIFIER().getText()); - rule.setConsequence(ctx.rhs().getText()); - packageDescr.addRule(rule); - return super.visitRuledef(ctx); + ruleDescr = new RuleDescr(ctx.name.getText()); + ruleDescr.setConsequence(ctx.rhs().getText()); + packageDescr.addRule(ruleDescr); + + Object result = super.visitRuledef(ctx); + ruleDescr = null; + return result; + } + + @Override + public Object visitLhsPatternBind(DRLParser.LhsPatternBindContext ctx) { + if ( ctx.lhsPattern().size() == 1 ) { + PatternDescr patternDescr = new PatternDescr(ctx.lhsPattern(0).objectType.getText()); + if (ctx.label() != null) { + patternDescr.setIdentifier(ctx.label().ID().getText()); + } + ruleDescr.getLhs().addDescr(patternDescr); + } + return super.visitLhsPatternBind(ctx); + } + + @Override + public Object visitAnnotation(DRLParser.AnnotationContext ctx) { + AnnotationDescr annotationDescr = new AnnotationDescr(ctx.name.getText()); + annotationDescr.setValue(ctx.arguments().argument(0).getText()); + ruleDescr.addAnnotation(annotationDescr); + return super.visitAnnotation(ctx); + } + + @Override + public Object visitAttribute(DRLParser.AttributeContext ctx) { + AttributeDescr attributeDescr = new AttributeDescr( ctx.getChild(0).getText() ); + if (ctx.getChildCount() > 1) { + attributeDescr.setValue( ctx.getChild(1).getText() ); + } + ruleDescr.addAttribute(attributeDescr); + return super.visitAttribute(ctx); } public PackageDescr getPackageDescr() { diff --git a/drools-drl/drools-drl10-parser/src/test/java/org/drools/parser/DRLParserTest.java b/drools-drl/drools-drl10-parser/src/test/java/org/drools/parser/DRLParserTest.java index fc99fc644cc..5d8bd5b42dd 100644 --- a/drools-drl/drools-drl10-parser/src/test/java/org/drools/parser/DRLParserTest.java +++ b/drools-drl/drools-drl10-parser/src/test/java/org/drools/parser/DRLParserTest.java @@ -2,7 +2,13 @@ import org.antlr.v4.runtime.RuleContext; import org.antlr.v4.runtime.tree.ParseTree; +import org.drools.drl.ast.descr.AnnotationDescr; +import org.drools.drl.ast.descr.AttributeDescr; +import org.drools.drl.ast.descr.BaseDescr; +import org.drools.drl.ast.descr.GlobalDescr; import org.drools.drl.ast.descr.PackageDescr; +import org.drools.drl.ast.descr.PatternDescr; +import org.drools.drl.ast.descr.RuleDescr; import org.junit.Test; import static org.drools.parser.DRLParserHelper.createParseTree; @@ -11,6 +17,7 @@ import static org.drools.parser.DRLParserHelper.isAfterSymbol; import static org.drools.parser.DRLParserHelper.parse; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; public class DRLParserTest { @@ -18,7 +25,8 @@ public class DRLParserTest { private static final String drl = "package org.test;\n" + "import org.test.model.Person;\n" + - "rule TestRule when \n" + + "global String result;\n" + + "rule TestRule @Test(true) no-loop salience 15 when \n" + " $p:Person()\n" + "then\n" + " System.out.println($p.getName());\n" + @@ -32,15 +40,38 @@ public void testParse() { assertEquals(1, packageDescr.getImports().size()); assertEquals("org.test.model.Person", packageDescr.getImports().get(0).getTarget()); + assertEquals(1, packageDescr.getGlobals().size()); + GlobalDescr globalDescr = packageDescr.getGlobals().get(0); + assertEquals("String", globalDescr.getType()); + assertEquals("result", globalDescr.getIdentifier()); + assertEquals(1, packageDescr.getRules().size()); - assertEquals("TestRule", packageDescr.getRules().get(0).getName()); - assertEquals("System.out.println($p.getName());", packageDescr.getRules().get(0).getConsequence()); + RuleDescr ruleDescr = packageDescr.getRules().get(0); + + AnnotationDescr annotationDescr = ruleDescr.getAnnotation("Test"); + assertNotNull(annotationDescr); + assertEquals("true", annotationDescr.getValue()); + + assertEquals( 2, ruleDescr.getAttributes().size() ); + assertNotNull( ruleDescr.getAttributes().get("no-loop") ); + AttributeDescr salience = ruleDescr.getAttributes().get("salience"); + assertNotNull( salience ); + assertEquals( "15", salience.getValue() ); + + assertEquals("TestRule", ruleDescr.getName()); + + assertEquals( 1, ruleDescr.getLhs().getDescrs().size() ); + PatternDescr patternDescr = (PatternDescr) ruleDescr.getLhs().getDescrs().get(0); + assertEquals("$p", patternDescr.getIdentifier()); + assertEquals("Person", patternDescr.getObjectType()); + + assertEquals("System.out.println($p.getName());", ruleDescr.getConsequence()); } @Test public void testCursorPosition() { ParseTree parseTree = createParseTree(drl); - ParseTree node = findNodeAtPosition(parseTree, 4, 7); + ParseTree node = findNodeAtPosition(parseTree, 5, 7); assertEquals("Person", node.getText()); ParseTree lhs = findParentOfType(node, DRLParser.RULE_lhs); assertEquals(DRLParser.RULE_lhs, ((RuleContext) lhs).getRuleIndex()); @@ -50,8 +81,8 @@ public void testCursorPosition() { @Test public void testCursorPosition2() { ParseTree parseTree = createParseTree(drl); - ParseTree node = findNodeAtPosition(parseTree, 3, 19); + ParseTree node = findNodeAtPosition(parseTree, 4, 51); assertEquals("when", node.getText()); - assertTrue(isAfterSymbol(node, DRLParser.WHEN, 3, 19)); + assertTrue(isAfterSymbol(node, DRLParser.WHEN, 4, 51)); } }