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"); :} ;