The grammar is given in CUP format (see http://www.cc.gatech.edu/gvu/people/Faculty/hudson/java_cup) which implements YACC in Java.
statement::=
no_parallel_statement:s {: RESULT.inst = s.inst; :}
| parallel_statement:s {: RESULT.inst = s.inst; :}
;
no_parallel_statement::=
sequence:s {: RESULT.inst = s.inst; :}
| stat:s {: RESULT.inst = s.inst; :}
;
parallel_statement::=
no_parallel_statement:s1 PAR no_parallel_statement:s2
{: RESULT.inst = new Merge(s1.inst,s2.inst); :}
| no_parallel_statement:s1 PAR parallel_statement_list:s2
{: RESULT.inst = new Merge(s1.inst,s2.inst); :}
;
parallel_statement_list::=
no_parallel_statement:s1 PAR no_parallel_statement:s2
{: RESULT.inst = new Merge(s1.inst,s2.inst); :}
| parallel_statement_list:s1 PAR no_parallel_statement:s2
{: RESULT.inst = new Merge(s1.inst,s2.inst); :}
;
sequence::=
pure_sequence:s {: RESULT.inst = s.inst; :}
| stat:s SEMI {: RESULT.inst = s.inst; :}
| pure_sequence:s SEMI {: RESULT.inst = s.inst; :}
;
pure_sequence::=
stat:s1 SEMI stat:s2
{: RESULT.inst = new Seq(s1.inst,s2.inst); :}
| pure_sequence:s1 SEMI stat:s2
{: RESULT.inst = new Seq(s1.inst,s2.inst); :}
;
stat::=
NOTHING {: RESULT.inst = new Nothing(); :}
| STOP {: RESULT.inst = new Stop(); :}
| HALT {: RESULT.inst = new Loop(new Stop()); :}
| NEXT {: RESULT.inst = new Next(); :}
| LPAREN statement:s RPAREN {: RESULT.inst = s.inst; :}
| break:s {: RESULT.inst = s.inst; :}
| extcode:s {: RESULT.inst = s.inst; :}
| if:s {: RESULT.inst = s.inst; :}
| loop:s {: RESULT.inst = s.inst; :}
| repeat:s {: RESULT.inst = s.inst; :}
| event_declaration:s {: RESULT.inst = s.inst; :}
| in_declaration:s {: RESULT.inst = s.inst; :}
| out_declaration:s {: RESULT.inst = s.inst; :}
| inout_declaration:s {: RESULT.inst = s.inst; :}
| generate:s {: RESULT.inst = s.inst; :}
| when :s {: RESULT.inst = s.inst; :}
| until:s {: RESULT.inst = s.inst; :}
| await:s {: RESULT.inst = s.inst; :}
| control:s {: RESULT.inst = s.inst; :}
| behavior:s {: RESULT.inst = s.inst; :}
| add:s {: RESULT.inst = s.inst; :}
| run:s {: RESULT.inst = s.inst; :}
| send:s {: RESULT.inst = s.inst; :}
| object:s {: RESULT.inst = s.inst; :}
| destroy:s {: RESULT.inst = s.inst; :}
;
/* java code */
extcode::= EXTCODE:e {: RESULT.inst = new ExternAtom(e.str_val); :} ;
/* test statement */
if::= IF EXTCODE:cond then_branch:t else_branch:e END
{: RESULT.inst = new If(cond.str_val,t.inst,e.inst); :}
;
then_branch::=
/* Empty */ {: RESULT.inst = new Nothing(); :}
| THEN statement:s {: RESULT.inst = s.inst; :}
;
else_branch::=
/* Empty */ {: RESULT.inst = new Nothing(); :}
| ELSE statement:s {: RESULT.inst = s.inst; :}
;
/* event configurations */
config::=
basic_config:c {: RESULT.conf = c.conf; :}
| config:c1 OR basic_config:c2
{: RESULT.conf = new OrConfig(c1.conf,c2.conf); :}
| config:c1 AND basic_config:c2
{: RESULT.conf = new AndConfig(c1.conf,c2.conf); :}
;
basic_config::=
IDENTIFIER :i {: RESULT.conf = new PosConfig(i.str_val); :}
| NOT IDENTIFIER:i {: RESULT.conf = new NegConfig(i.str_val); :}
| LPAREN config:c RPAREN {: RESULT.conf = c.conf; :}
;
/* event based statements */
await::= AWAIT config:c {: RESULT.inst = new Await(c.conf); :} ;
event_declaration::=
EVENT identifier_list:l IN statement:s END
{: RESULT.inst = semActions.eventDecl(l.list,s.inst); :}
;
in_declaration::=
INPUT IDENTIFIER:intern IS IDENTIFIER:extern IN statement:s END
{: RESULT.inst =
new InputDecl(intern.str_val,extern.str_val,s.inst); :}
;
out_declaration::=
OUTPUT IDENTIFIER:intern IS IDENTIFIER:extern IN statement:s END
{: RESULT.inst =
new OutputDecl(intern.str_val,extern.str_val,s.inst); :}
;
inout_declaration::=
INPUTOUTPUT IDENTIFIER:intern IS IDENTIFIER:extern IN statement:s END
{: RESULT.inst =
new InOutDecl(intern.str_val,extern.str_val,s.inst); :}
;
generate::= GENERATE IDENTIFIER:i
{: RESULT.inst = new Generate(i.str_val); :} ;
when::= WHEN config:c then_branch:t else_branch:e END
{: RESULT.inst = new When(c.conf,t.inst,e.inst); :} ;
until::= DO statement:s UNTIL config:c actual:a
{: RESULT.inst = new Until(c.conf,s.inst,a.inst); :} ;
actual::=
/*Empty*/ {: RESULT.inst = new Nothing(); :}
| ACTUAL statement:s END {: RESULT.inst = s.inst; :} ;
control::= CONTROL statement:s BY IDENTIFIER:i
{: RESULT.inst = new Control(i.str_val,s.inst); :} ;
/* identifier lists */
identifier_list::=
IDENTIFIER:i {: RESULT.list.addElement(i.str_val); :}
| identifier_list:l COLON IDENTIFIER:i
{: RESULT.list = semActions.addToIdentifierList(l.list,i.str_val); :}
;
/* loops */
loop::= LOOP statement:s END
{: RESULT.inst = new EventDecl("_break",new Until("_break",
new Loop(s.inst))); :}
;
break::= BREAK
{: RESULT.inst = new Seq(new Generate("_break"),new Stop()); :} ;
repeat::= LOOP EXTCODE:e TIMES statement:s END
{:
RESULT.inst = new EventDecl("_break",new Until("_break",
new Repeat(External.parseIntExpression(e.str_val),s.inst)));
:} ;
/******************** behaviors ********************/
behavior::=
BEHAVIOR IDENTIFIER:i behavior_interface:l statement:s END
{: RESULT.inst = new Behavior(i.str_val,l.list,s.inst); :}
;
behavior_interface::= /* Empty */ {: RESULT.list = null; :}
| interface_list:l {: RESULT.list = l.list; :}
;
interface_list::=
interface:i {: RESULT.list = i.list; :}
| interface_list:l interface:i
{: RESULT.list = Param.concat(l.list,i.list); :}
;
interface::=
IN identifier_list:l SEMI
{: RESULT.list = Param.convert(ParamTypes.IN_PARAM,l.list); :}
| OUT identifier_list:l SEMI
{: RESULT.list = Param.convert(ParamTypes.OUT_PARAM,l.list); :}
| INOUT identifier_list:l SEMI
{: RESULT.list = Param.convert(ParamTypes.INOUT_PARAM,l.list); :}
;
call::=
IDENTIFIER:i {: RESULT.inst = new Run(i.str_val); :}
| IDENTIFIER:i LPAREN identifier_list:l RPAREN
{: RESULT.inst = new Run(i.str_val,l.list); :}
;
run::= RUN call:c {: RESULT.inst = c.inst; :} ;
add::= ADD statement:s TO IDENTIFIER:i
{: RESULT.inst = new AddTo(i.str_val,s.inst); :} ;
/******************** objects ********************/
object::=
OBJECT IDENTIFIER:o statement:s END
{: RESULT.inst = semActions.object(o.str_val,s.inst); :}
| OBJECT IDENTIFIER:o object_behavior:s METHODS object_methods:l END
{: RESULT.inst = semActions.object(o.str_val,s.inst,l.list); :}
;
object_behavior::=
/* Empty */ {: RESULT.inst = new Nothing(); :}
| statement:s {: RESULT.inst = s.inst; :}
;
object_methods::=
call:c {: RESULT.list.addElement(c.inst); :}
| object_methods:l call:c
{: l.list.addElement(c.inst); RESULT.list = l.list; :}
;
send::= SEND IDENTIFIER:m TO IDENTIFIER:o
{: RESULT.inst = new Generate(o.str_val + "-" + m.str_val); :}
;
destroy::= DESTROY IDENTIFIER:o
{: RESULT.inst = new Generate(o.str_val + "-destroy"); :}
;