/* * Copyright 2008 Marc Bischof * based on simpel.g by Matthieu Riou *  * Licensed under the Apache License, Version 2.0 (the "License");  * you may not use this file except in compliance with the License.  * You may obtain a copy of the License at *  *      http://www.apache.org/licenses/LICENSE-2.0 *  * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License. */ grammar BPELscript; options { output=AST; ASTLabelType=CommonTree; } tokens { ROOT; PROCESS; PICK; SEQUENCE; FLOW; FLOWS; IF; ELSIF; ELSE; WHILE; UNTIL; FOR; INVOKE;PROC_STMTS; RECEIVE; REPLY; ASSIGN; THROW; WAIT; EXIT; TIMEOUT; TRY; CATCH; CATCH_ALL; SCOPE; EVENT; ALARM; ONMESSAGE; COMPENSATION; COMPENSATE; CORRELATION; CORR_MAP; PARTNERLINK; VARIABLE; VALIDATE; BLOCK_PARAM; SIGNAL; JOIN; WITH; MAP; NOP; RETHROW; EXPR; EXT_EXPR; XML_LITERAL; CALL; NAMESPACE; NS; PATH; EXTENSION; EXTENSIONACT; IMPORT; MESSAGES; CORRSETS; CORRSET; XML; JS; PID; VARIABLES; PARTNERLINKS; PORTTYPE; STD_ATTR;ONALARM;REPEATEVERY;EVENTHDL;MESSAGE; TERMINATION; MSGEX; FAULTNAME; MSGTYPE; VITYPE; VIELT;FAULTELT; } @parser::header { /* * Copyright 2008 Marc Bischof * based on simpel.g by Matthieu Riou *  * Licensed under the Apache License, Version 2.0 (the "License");  * you may not use this file except in compliance with the License.  * You may obtain a copy of the License at *  *      http://www.apache.org/licenses/LICENSE-2.0 *  * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License. */ package iaas.bpelscript.antlr;} @lexer::header { /* * Copyright 2008 Marc Bischof * based on simpel.g by Matthieu Riou *  * Licensed under the Apache License, Version 2.0 (the "License");  * you may not use this file except in compliance with the License.  * You may obtain a copy of the License at *  *      http://www.apache.org/licenses/LICENSE-2.0 *  * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License. */ package iaas.bpelscript.antlr;} // MAIN BPEL SYNTAX program : declaration+ -> ^(ROOT declaration+); declaration : process | sub_declaration; sub_declaration : namespace | extension | imports; // Process process : ('@queryLanguage' queryLg=STRING)? ('@expressionLanguage' exprLg=STRING)? sjf=SJF? exitOnStandardFault=EOSF? 'process' ns_id std_attr j+=ajoin? s+=asignal* block eventHdl? -> ^(PROCESS ns_id block eventHdl? $queryLg? $exprLg? $sjf? $exitOnStandardFault? std_attr ajoin? asignal*); proc_stmts : (join SEMI)? proc_stmt (s+=signal SEMI)* -> ^(PROC_STMTS join? signal* proc_stmt); proc_stmt : //structured stmts if_ex | flow | pick | while_ex | until_ex | foreach | scope_ex | ext_act | try_ex | corr_sets //simple stmts | ((invoke | receive | reply | assign | throw_ex | rethrow_ex | alarm | timeout | exit | variables | validate | partner_links | compensate | nop | messages) SEMI!); block : '{' proc_stmts+ '}' -> ^(SEQUENCE proc_stmts+); scope_block : '{' sub_declaration* proc_stmts+ '}' -> ^(SEQUENCE sub_declaration* proc_stmts+); param_block : '{' ('|' in+=ID (',' in+=ID)* '|')? proc_stmts+ '}' -> ^(SEQUENCE $in* proc_stmts+); body : block | proc_stmts; // Structured activities pick : CREATE_INST? std_attr 'pick' '{' onMessage+ onAlarm* '}' -> ^(PICK onMessage+ onAlarm* CREATE_INST? std_attr); onMessage : portType? msgEx? 'onMessage' '(' p=ID ',' o=ID (',' correlation)? ')' with_ex? param_block -> ^(ONMESSAGE param_block portType? msgEx? ID ID correlation? with_ex?); onAlarm : // use syntactic predicate to garantie that at least one expression must be there // (also garanties that standard attributes are not used in this context) {input.LT(1).getText().equals("alarm") || input.LT(1).getText().equals("timeout") || input.LT(1).getText().equals("repeatEvery")}? (alarm | timeout)? repeatEvery? {input.LT(1).getText().equals("{")}? scope_short -> ^(ONALARM alarm? timeout? repeatEvery? scope_short); alarm : std_attr 'alarm' '(' expr ')' -> ^(ALARM expr std_attr?); timeout : std_attr 'timeout' '('expr ')' -> ^(TIMEOUT expr std_attr?); repeatEvery : 'repeatEvery' '(' expr ')' -> ^(REPEATEVERY expr); flow : std_attr 'parallel' s+=sequence ( 'and' s+=sequence)* -> ^(FLOW $s+ std_attr) ; signal : 'signal' '('ID (',' expr)? ')' -> ^(SIGNAL ID expr?); asignal : '@signal' '('ID (',' expr)? ')' -> ^(SIGNAL ID expr?); ajoin : '@join' '(' k+=ID (',' k+=ID)* (',' expr)? ')' -> ^(JOIN $k+ expr?); join : 'join' '(' k+=ID (',' k+=ID)* (',' expr)? ')' -> ^(JOIN $k+ expr?); if_ex : std_attr 'if' '(' iex=expr ')' s=sequence ('elseif' '(' eiex+=expr ')' sei+=sequence)* ('else' se=sequence)? -> ^(IF $iex $s (^(ELSIF $eiex $sei))* (^(ELSE $se))? std_attr); sequence : std_attr j+=ajoin? s+=asignal* b=body -> ^(SEQUENCE $j? $b $s* std_attr); scope_sequence : j+=ajoin? s+=asignal* b=scope_block -> ^(SEQUENCE $j? $b $s*); while_ex : std_attr 'while' '(' expr ')' s=sequence -> ^(WHILE expr sequence std_attr); until_ex : std_attr 'repeat' s=sequence 'until' '(' expr ')' -> ^(UNTIL expr sequence std_attr); foreach : PARALLEL? successfulBranchesOnly=SBO? std_attr 'for' '(' cName=ID '=' init=expr ('to'|SEMI) cond=expr (('finish'|SEMI) complete+=expr)? ')' scope_short -> ^(FOR $cName $init $cond $complete? scope_short PARALLEL? SBO? std_attr); try_ex : 'try' body catch_ex* catchAll?-> ^(TRY catch_ex* body?); catch_ex : (('@faultMessageType' fMT=STRING) | faultElt)? 'catch' '(' ns_id faultVar=ID? ')' block -> ^(CATCH ns_id block $faultVar? $fMT? faultElt?); catchAll : 'catchAll' block -> ^(CATCH block); scope_ex : ISOLATED? EOSF? SJF? 'scope' ('(' ID? ')')? scope_sequence scope_stmt -> ^(SCOPE ID? scope_stmt scope_sequence ISOLATED? EOSF? SJF?); scope_short : scope_sequence scope_stmt -> ^(SCOPE scope_stmt scope_sequence); scope_stmt : compensation? termination? eventHdl? -> ^(SCOPE compensation? termination? eventHdl?); termination : 'onTermination' body -> ^(TERMINATION body); eventHdl : 'events' '{' onEvent* onAlarm* '}' -> ^(EVENTHDL onEvent* onAlarm*); onEvent : portType? msgEx? ( msgType | viElt )? (var=ID '=' )? 'event' '(' p=ID ',' o=ID (',' correlation)? ')' with_ex? scope_short -> ^(EVENT $p $o correlation? with_ex? scope_short $var? portType? msgEx? msgType? viElt?); compensation //compensation handler : 'compensation' body -> ^(COMPENSATION body); with_ex : 'with' '(' wm+=with_map (',' wm+=with_map)* ')' -> ^(WITH $wm+); with_map : ID ':' KEY? path_expr -> ^(MAP ID KEY? path_expr); // Simple activities receive : portType? CREATE_INST? msgEx? std_attr 'receive' '(' p=ID ',' o=ID (',' correlation)? ')' with_ex? -> ^(RECEIVE $p $o correlation? portType? CREATE_INST? msgEx? std_attr with_ex?); reply : portType? faultName? msgEx? std_attr 'reply' '(' p=ID ',' o=ID (',' in=ID)? (',' correlation)? ')' with_ex? -> ^(REPLY ID ID ID? correlation? portType? std_attr faultName? msgEx? with_ex?); invoke : portType? std_attr 'invoke' '(' p=ID ',' o=ID (',' in=ID)? (',' correlation)? ')' with_ex? compensation? -> ^(INVOKE $p $o $in? correlation? portType? std_attr with_ex? compensation?); assign : portType? CREATE_INST? VALID? KEEPSRC? IGNORE? faultName? msgEx? std_attr //only receive and invoke path_expr PART? '=' rvalue -> ^(ASSIGN path_expr PART? portType? CREATE_INST? std_attr faultName? msgEx? VALID? KEEPSRC? IGNORE? rvalue); rvalue : receive | invoke | expr PART?; throw_ex : (('@faultVariable' |'@faultVar') faultVar=ID)? std_attr 'throw' '(' ns_id ')' -> ^(THROW ns_id $faultVar? std_attr); rethrow_ex : std_attr 'rethrow' -> ^(RETHROW std_attr); compensate : std_attr 'compensate' ('(' target=ID ')')? -> ^(COMPENSATE ID? std_attr); exit : std_attr 'exit' -> ^(EXIT std_attr); validate : std_attr 'validate' v+=ID (',' v+=ID)*-> ^(VALIDATE $v+ std_attr); ext_act : std_attr e=EXT_ACT -> ^(EXTENSIONACT $e std_attr); nop : std_attr 'nop' -> ^(NOP std_attr); // Others namespace : 'namespace' ID '=' STRING SEMI -> ^(NAMESPACE ID STRING); extension : MUSTUND? 'extension' ID '=' STRING SEMI -> ^(EXTENSION ID STRING MUSTUND?); imports : viType 'import' (id=ID '=' (ns=ID '::' )? loc=STRING ) SEMI -> ^(IMPORT $id $loc $ns? viType?); messages //Exchange : 'messages' m+=message (',' m+=message)* -> ^(MESSAGES message+); message : ID -> ^(MESSAGE ID); variables : 'var' v+=variable (',' v+=variable)* -> ^(VARIABLES variable+); variable : msgType? viType? viElt? ID with_ex? -> ^(VARIABLE ID msgType? viType? viElt? with_ex?); partner_links : ('partnerLink' | 'partnerlink') pl+=partner_link (',' pl+=partner_link)* -> ^(PARTNERLINKS $pl+); partner_link : ID '=' '(' plType=ns_id? (',' roleA=ns_id)? (',' roleB=ns_id)? (',' init=INITPARTNER)? ')' -> ^(PID ID $plType? $roleA? $roleB? $init?); correlation : '{' corr_mapping (',' corr_mapping)* '}' -> ^(CORRELATION corr_mapping+); corr_mapping : init=INIT_COR? pattern=PATTERN_COR? f1=ID -> ^(CORR_MAP $f1 $init? $pattern?); corr_sets : 'correlates' '{'cs+=corr_set ';' (cs+=corr_set ';')* '}' -> ^(CORRSETS $cs+); corr_set : f=ID '(' par+=ID (',' par+=ID)* ')' -> ^(CORRSET $f $par+); // Expressions expr : s_expr | EXT_EXPR | funct_call; funct_call : p+=ID '(' p+=ID* ')' -> ^(CALL ID+); s_expr : condExpr; condExpr : aexpr ( ('==' ^|'!=' ^|'<' ^|'>' ^|'<=' ^|'>=' ^) aexpr )?; aexpr : mexpr (('+'|'-') ^ mexpr)*; mexpr : atom (('*'|'/') ^ atom)* | STRING; atom : path_expr | INT | '(' s_expr ')' -> s_expr; path_expr : pelmt+=ns_id ('.' pelmt+=ns_id)* -> ^(PATH $pelmt+); ns_id : (pr=ID '::')? loc=ID -> ^(NS $pr? $loc); //optional attributes portType : ('@portType' | '@pt') STRING -> ^(PORTTYPE STRING); std_attr : ('@name' name=STRING)? suppressJoinFailure=SJF? -> ^(STD_ATTR $name? $suppressJoinFailure?); msgEx : ('@messageExchange' | '@mex') STRING -> ^(MSGEX STRING); msgType : ('@messageType' | '@msgType') msgT=STRING -> ^(MSGTYPE STRING); //var or import type viType : '@type' type=STRING -> ^(VITYPE STRING); viElt : '@element' elt=STRING -> ^(VIELT STRING); faultName : ('@faultName' | '@fault') STRING -> ^(FAULTNAME STRING); faultElt : '@faultElement' STRING -> ^(FAULTELT STRING); // LEXER RULES EXT_EXPR : '[' (options {greedy=false;} : .)* ']'; EXT_ACT : pre='{{{' (options {greedy=false;} : c=.)* post='}}}'; // Basic tokens KEY : 'in' | 'out' | 'inout'; SEMI : ';'; ID : (LETTER | '_' ) (LETTER | DIGIT | '_' | '-' )*; INT : (DIGIT )+ ; STRING : '"' ( ESCAPE_SEQ | ~('\\'|'"') )* '"'; ESCAPE_SEQ : '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\'); SL_COMMENTS : ('#'|'//') .* CR { $channel = HIDDEN; }; CR : ('\r' | '\n' )+ { $channel = HIDDEN; }; WS : ( ' ' | '\t' )+ { skip(); }; fragment DIGIT : '0'..'9'; fragment LETTER : 'a'..'z' | 'A'..'Z'; // Boolean annotations as LEXER rules protected EOSF : ('@exitOnStandardFault' | '@exit') {setText("exitOnStandardFault=\"yes\"");} | ('@exitOnStandardFault no' | '@exit no') {setText("exitOnStandardFault=\"no\"");}; protected SJF : ('@suppressJoinFailure' | '@dpe') {setText("suppressJoinFailure=\"yes\"");} | ('@suppressJoinFailure no' | '@dpe no') {setText("suppressJoinFailure=\"no\"");}; protected PARALLEL : ('@parallel' | '@par') {setText("parallel=\"yes\"");} | ('@parallel no' | '@par no') {setText("parallel=\"no\"");}; protected SBO : ('@successfulBranchesOnly' | '@success' | '@sbo') {setText("successfulBranchesOnly=\"yes\"");} | ('@successfulBranchesOnly no' | '@sbo no') {setText("successfulBranchesOnly=\"no\"");}; protected INITPARTNER : ('@initializePartner' | '@init') {setText("initializePartnerRole=\"yes\"");} | ('@initializePartner no' | '@init no') {setText("initializePartnerRole=\"no\"");}; protected INIT_COR : ('!' | 'force') {setText("initiate=\"yes\"");} | ('?' | 'join') {setText("initiate=\"join\"");}; protected PATTERN_COR : ('@>' | 'request') {setText("pattern=\"request\"");} | ('@<' | 'response') {setText("pattern=\"response\"");} | ('@><' | 'request-response') {setText("pattern=\"request-response\"");}; protected ISOLATED : '@isolated' {setText("isolated=\"yes\"");} | '@isolated no' {setText("isolated=\"no\"");}; protected CREATE_INST : ('@createInstance' | '@ci') {setText(" createInstance=\"yes\"");} | ('@createInstance no' | '@ci no') {setText(" createInstance=\"not\"");}; protected VALID : '@validate' {setText("validate=\"yes\"");} | '@validate no' {setText("validate=\"no\"");} ; protected KEEPSRC : ('@keepSrcElementName' | '@keepSrc') {setText("keepSrcElementName=\"yes\"");} | ('@keepSrcElementName no' | '@keepSrc no') {setText("keepSrcElementName=\"no\"");}; protected IGNORE : '@ignoreMisssingFromData' | '@ignore' {setText("ignoreMisssingFromData=\"yes\"");} | ('@ignoreMisssingFromData no' | '@ignore no') {setText("ignoreMisssingFromData=\"no\"");}; protected PART : '@part' {setText("part");}; protected MUSTUND : '@mustUnderstand' {setText("mustUnderstand=\"yes\"");} | '@mustUnderstand no' {setText("mustUnderstand=\"no\"");};