123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669 |
- -- MP_generator.rig Phoenix -> C++ code generator
- -- V 2.0
- -- Mikhail Auguston, 03/05/15
- -- last modified 04/05/15
- -- use: MP_generator intermediate_file
- --
- -----------------------------------
- #AG
- -- Globals:
- -- $roots -- retain the original MP code,
- -- $composites -- these are used for comment generation
- -- $atoms -- for event name generation
- -- $new_root_table
- -- $new_composites
- -- $composite_order -- for harvest() calls ordering
- -- $class_counter
- -- $generated_containers: <* work_name: T *>
- ----------------------------------------------
- $Parm:= #PARM(T);
- $input_file:= #IMPLODE( $Parm [1]);
- LOAD $model $input_file;
- $roots:= $model.roots;
- $composites:= $model.composites;
- $atoms:= $model.atomic_events;
- $new_root_table:= $model.new_root_table;
- $new_composites:= $model.new_composites;
- $composite_order:= $model.composite_order;
- $coordinate_ops:= $model.coordinate_ops;
- $share_all_ops:= $model.share_all_ops;
-
- OPEN GEN #IMPLODE( $model.schema '.cpp' ); -- for C++ code
- OPEN MSG ' '; --for error messages
- --MSG<< 'Phoenix/C++ generator v.2.0 input from ' $input_file;
-
- GEN<< '/* Monterey Phoenix-> C++ generator, v.2.0, March 2015';
- GEN<< ' Mikhail Auguston, NPS, CS Dept, Monterey, CA, USA';GEN<<;
- GEN<< ' traces derived for scope' $model.scope;
- GEN<< '----------------------------------------------------';
- GEN<< 'SCHEMA' $model.schema;
- -- print comments with the original MP code
- #print_rule_list(root $roots);
- #print_rule_list(composite $composites);
-
- GEN<<;
- GEN<< '*****************************************************************';
- GEN<< '***' generated constants are visible in the 'mp2_print_etc.h';
- GEN<< '*****************************************************************/';
- GEN<< '#include "mp2.h" // the permanent part';GEN<<;
-
- #generate_event_names();
- #generate_event_strings();
- GEN<< '#include "mp2_print_etc.h" // print methods';
- GEN<< '//***************************';
- GEN<< '//==== generated classes ====';
- GEN<< '//***************************';
- GEN<<;
-
- $class_counter:= 0;
- #generate_composite_producers($new_composites);
- #generate_composite_producers($new_root_table);
- #generate_event_class($new_composites);
- #generate_event_class($new_root_table);
- #generate_coordination_class($coordinate_ops);
- #generate_share_all_class($share_all_ops);
- #generate_schema_class($model.elt_list);
-
- GEN<< '//******************************************';
- GEN<< '//' main;
- GEN<< '//******************************************';
- GEN<< 'int main(){';
- GEN<< ' gen_start = clock();';
- GEN<< @ ' JSON.open("' $model.schema '.json");';
- GEN<< ' cout<< "generating traces for scope' $model.scope '"<<endl;';
- GEN<< '//----------------------------';
- #generate_harvest_calls($composite_order);
- #harvest_roots($new_root_table);
- #harvest_main_schema();
- -- generate statistics show
- GEN<< '//----------------------------';
- GEN<< ' show_statistics();';
- GEN<< 'return 0;';
- GEN<< '} // end main()';
- ##
- --------------------------------------------------
- -- print subroutines ----------------------------
- --------------------------------------------------
- #print_rule_list
- -- Global: $buffer_len -- should be <= 80
- ( root /$type:= ROOT/ ! $x)
- <* $rule_name:
- /GEN<< $type @ $rule_name ': ';
- $buffer_len:= #LEN($rule_name) + 10/
- <. pattern_list: #print_element .>
- / GEN<] ';'/
- *>
- ##
- #print_element
- <. type: plain,
- name: $event_name
- /IF LAST #print_rule_list $buffer_len + #LEN($event_name) > 68 ->
- GEN<< ' ';
- LAST #print_rule_list $buffer_len:= 10
- FI;
- GEN<] $event_name;
- LAST #print_rule_list $buffer_len +:= #LEN($event_name) +1/
- .>;;
- <. type: sequence,
- body: (. (* #print_element *) .)
- .>;;
-
- <. type: alternative,
- body: /GEN<] '('/
- (. (* /GEN<] $bar; $bar:= '|'/ #print_element *) .)
- /GEN<] ')'/
- .>;;
- <. type: iterator,
- body: /GEN<] '(*'/ #print_element /GEN<] '*)'/
- .>;;
- <. type: iterator_plus,
- body: /GEN<] '(+'/ #print_element /GEN<] '+)'/
- .>;;
-
- <. type: set,
- body: /GEN<] '{'/
- (. (* /GEN<] $bar; $bar:= ','/ #print_element *) .)
- /GEN<] '}'/
- .>;;
- <. type: set_iterator,
- body: /GEN<] '{*'/ #print_element /GEN<] '*}'/
- .>;;
- <. type: set_iterator_plus,
- body: /GEN<] '{+'/ #print_element /GEN<] '+}'/
- .>;;
-
- <. type: optional,
- body: /GEN<] '['/ #print_element /GEN<] ']'/
- .>;;
-
- <. type: empty .> ;; -- EMPTY
- $x /GEN<< '**' $x.type print not implemented yet '**'/
- ##
- ------------------------------------------------------------------
- -------- generate event names enum and strings
- ------------------------------------------------------------------
- -- GenericContainer is used for all Alt (OR), Seq (AND), Set producers
- #generate_event_names
- /GEN<< 'enum Event_name {Dummy_event, GenericContainer';
- GEN<< ' // atomic events';
- #print_event_name(LAST #AG $atoms);
- GEN<< ' // composite events';
- #print_event_name(LAST #AG $composites);
- GEN<< ' // coordination operations';
- #print_event_name(LAST #AG $coordinate_ops);
- GEN<< ' // share all operations';
- #print_event_name(LAST #AG $share_all_ops);
- GEN<< ' // ROOT events';
- #print_event_name(LAST #AG $roots);
- GEN<< ' // main schema event';
- GEN<< @ ' , Event_' LAST #AG $model.schema;
- GEN<] ' };'; GEN<<;/
- ##
- #print_event_name
- <* $event_name: $x
- /GEN<< @ ' , Event_' $event_name /
- *>
- ##
- #generate_event_strings
- /GEN<< 'string event_name_string[] = {"Dummy", "GenericContainer"';
- #print_event_string(LAST #AG $atoms);
- #print_event_string(LAST #AG $composites);
- #print_event_string(LAST #AG $coordinate_ops);
- #print_event_string(LAST #AG $share_all_ops);
- #print_event_string(LAST #AG $roots);
- GEN<< @ ' , "' LAST #AG $model.schema '"';
- GEN<] ' };'; GEN<<;/
- ##
- #print_event_string
- <* $event_name: $x
- /GEN<< @ ' , "' $event_name '"' /
- *>
- ##
- --********************************************************************
- --------------------------- EVENT CLASSES ----------------------------
- --********************************************************************
- #generate_composite_producers
- <* $event_name: <. pattern_list: #generate_container,
- [build_block: $comp_op_list
- -- here comes composition op class generator <<<<<<<<<<
- ]
- .>
- *>
- ##
- #generate_container
- <. type: ( plain ! composite ! empty ) .> ;;
-
- -- for event grammar patterns
- <. name: $work_name
- /IF LAST#AG $generated_containers.$work_name ->
- RETURN T
- FI/, -- to prevent duplication
-
- type: ( sequence /$base:= AND_node_producer_container/ !
- alternative /$base:= OR_node_producer_container/ !
- set /$base:= SET_node_producer_container/ ),
-
- body: (. (* #generate_container *) .), -- for nested ALT, SEQ, SET
- body:
- /GEN<< '//----' #class_counter() '----';
- GEN<< class $work_name ': public' $base '{';
- GEN<< 'public:' '//' constructor;
- GEN<< ' ' $work_name '():' $base '(GenericContainer){';
- GEN<< ' element = new Event_producer_ref[ element_count ='
- #LEN($.body) + #LEN(LAST #generate_composite_producers $comp_op_list)
- '];';
- $element_count:= 0 /
- (. (* /GEN<< ' element[' $element_count ']= '/
- #generate_element
- /GEN<] ';';
- $element_count +:= 1 /
- *) .)
- .>
-
- /GEN<< ' }';
- GEN<< '};//' end class $work_name;
- GEN<<;
- LAST#AG $generated_containers ++:= <. $work_name: T .> /
- ##
- #generate_element
- <. type: plain,
- name: $Id .>
- /GEN<] @ 'new Atomic_producer(Event_' $Id ')'/;;
- <. type: composite,
- name: $Id .>
- /GEN<] @ 'new Composite_secondary_producer(Event_' $Id ')'/;;
-
- <. type: (sequence ! alternative ! set),
- name: $work_name .>
- /GEN<] new $work_name/;;
-
- <. type: empty .>
- /GEN<] '&Dummy'/;;
-
- -- here come composition op elements <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-
- $x /PRINT (. '***' Unrecognized element $x .)/
-
- ##
- #generate_event_class
- <* $event_name:
- <. rule_type: ( composite /$target_event:= Composite_event_instance_node/ !
- ROOT /$target_event:= ROOT_node/ ),
-
- work_name: $work_name
- /GEN<< '//----' #class_counter() '----';
- GEN<< class $work_name ': public Composite_producer {';
- GEN<< 'public:' '//' constructor;
- GEN<< ' ' $work_name @ '(): Composite_producer(Event_' $event_name '){';
- GEN<< ' target_event =' $target_event ';';
- GEN<< ' element = new Event_producer_ref[ element_count ='
- 1 + #LEN($.$event_name.build_block) '];';
- $element_count:= 0 /,
-
- pattern_list: -- on the top level in composite always just single pattern
- /GEN<< ' element[' $element_count ']= '/
- #generate_element
- /GEN<] ';';
- $element_count +:= 1 /,
- [build_block: $comp_op_list ]
- .>
- /GEN<< ' }';
- GEN<< '};//' end class $work_name;
- GEN<< /
- *>
- ##
- #generate_coordination_class
- -- global:
- -- $nesting_depth for avoiding redundant create_matrices() calls
- -------------------------
- <* $work_name:
- /GEN<< '//----' #class_counter() '----';
- GEN<< class @ $work_name '_ob: public Coordinate {';
- GEN<< 'public:' '//' constructor;
- GEN<< ' ' @ $work_name '_ob(int n): Coordinate(n){ }';
- GEN<<;
- GEN<< ' Traversal_result traverse(){';
- GEN<< ' try{';
- $nesting_depth:= 0/
-
- #generate_operation
-
- /GEN<< ' }';
- GEN<< ' catch(Traversal_result t){';
- GEN<< ' delete_matrices();';
- GEN<< ' return failed;';
- GEN<< ' }';
- GEN<< ' delete_matrices();';
- GEN<< ' return success_and_completed;';
- GEN<< ' } // end traverse()';
- GEN<< '}; // end' @ $work_name '_ob class';
- GEN<</
- *>
- ##
- #generate_share_all_class
- <* $work_name:
- /GEN<< '//----' #class_counter() '----';
- GEN<< class @ $work_name '_ob: public Coordinate {';
- GEN<< 'public:' '//' constructor;
- GEN<< ' ' @ $work_name '_ob(int n): Coordinate(n){type = ShareAll_op;}';
- GEN<<;
- GEN<< ' Traversal_result traverse(){';
- GEN<< ' try{';/
-
- #generate_operation
-
- /GEN<< ' }';
- GEN<< ' catch(Traversal_result t){';
- GEN<< ' delete_matrices();';
- GEN<< ' return failed;';
- GEN<< ' }';
- GEN<< ' delete_matrices();';
- GEN<< ' return success_and_completed;';
- GEN<< ' } // end traverse()';
- GEN<< '}; // end' @ $work_name '_ob class';
- GEN<</
- *>
- ##
- #generate_operation
- /LAST #generate_coordination_class $nesting_depth +:= 1/
- <. synchronization: $synchronization,
- operation: COORDINATE
- /GEN<< ' //' $synchronization COORDINATE operation;
- GEN<< ' create_matrices();'/,
-
- source_list: <* $variable:
- /GEN<<;
- GEN<< ' int' $variable '; // variable';
- GEN<< @ ' vector<int> ' $variable
- '_list; // list of coordinated events' /
- <. from:
- ( <. comp: $source .>
- /$source_name:= #IMPLODE($source '_source');
- IF NOT $source_defined.$source ->
- GEN<< ' int ' $source_name
- '; // source of coordination';
- $source_defined++:= <. $source: T .>
- FI;
- GEN<<;
- GEN<< ' // find source event' $source;
- GEN<< ' for(int i = 0; i < Stack.size(); i++){';
- GEN<< @' if( Stack[i]->name == Event_' $source '){';
- GEN<< ' ' $source_name '= i; break; }';
- GEN<< ' }'/ !
- <. var: $v .>
- /$source_name:= $v/
- )
- /$source_list!.:= (. $variable $source_name .);
- $source_tree++:= <. $variable: $source_name .>/
- .>
- *>,
-
- -- second pass
- source_list: /GEN<<;
- GEN<< ' // create lists of coordinated events';
- GEN<< ' for(int i = 0; i < len; i++){'/
-
- <* $variable:
- /GEN<< ' if(in_matrix[i * len + ' $source_tree.$variable ']){';
- GEN<< @' if(';
- $or_op:= ' '/
- <. selection_pattern: (. (*
- /GEN<] @ $or_op '(Stack[i]->name == Event_' /
- $event_name
- /GEN<] @ $event_name ')';
- $or_op:= '||'/
- *) .)
- .>
- /GEN<] @ ' ){';
- GEN<< ' //' make sure this is fresh event not yet shared;
- GEN<< ' int found = 0;';
- GEN<< @' for(vector<int>:: iterator s = '
- $variable '_list.begin(); s != ' $variable '_list.end(); s++){';
- GEN<< ' if((found = eq_matrix[i * len + *s])) break;';
- GEN<< ' }';
- GEN<< @' if(!found) ' $variable '_list.push_back(i);';
- GEN<< ' }';
- GEN<< ' }'/
- *>
-
- /GEN<< ' }';
- IF #LEN($source_list) > 1 ->
- GEN<< ' //' check that selected lists are of the same length;
- GEN<< @ ' if(';
- $first_arg:= #IMPLODE($source_list[1][1] '_list.size() != ');
- $i:= 2;
- $or_op:= ' ';
- LOOP
- IF $i > #LEN($source_list) -> BREAK FI;
- GEN<] $or_op @ $first_arg $source_list[$i][1] '_list.size() ';
- $i +:= 1;
- $or_op:= '||';
- END;
- GEN<] ') throw failed;'
- FI/,
-
- synchronization: ( Synchronous
- /GEN<<;
- GEN<< ' //' for syncronized COORDINATE sort the list
- and check for total order;
- FORALL $var IN $source_list DO
- GEN<< @ ' sort_and_check_coordinated_events(' $var[1] '_list);'
- OD / !
- $a ),
-
- body: /GEN<<;
- GEN<< ' //' do the COORDINATE;
- GEN<< ' for(int i = 0; i <' #IMPLODE($source_list[1][1] '_list.size()') '; i++){';
- FORALL $var IN $source_list DO
- GEN<< @ ' ' $var[1] '= ' $var[1] '_list[i];'
- OD/
- (. (+
- ( <. operation:'ADD',
- relation_list: (. (+
- <.first: $var1,
- second: $var2,
- relation: ( PRECEDES
- /GEN<< @' Follows.insert(pair<int, int>(' $var2 ',' $var1 '));'/ !
- FOLLOWS
- /GEN<< @' Follows.insert(pair<int, int>(' $var1 ',' $var2 '));'/ !
- 'IN'
- /GEN<< @' Inside.insert(pair<int, int>(' $var1 ',' $var2 '));'/ !
- CONTAINS
- /GEN<< @' Inside.insert(pair<int, int>(' $var2 ',' $var1 '));'/
- )
- .>
- +) .)
- .> !
-
- #generate_operation !
-
- <. operation: $op .>
- /MSG<< '*****' operation $op is not yet implemented/
- )
- +)
- .)
- /GEN<< ' }';
- IF LAST #generate_coordination_class $nesting_depth < 2 ->
- GEN<< ' create_matrices(); //' to check for axiom violation;
- GEN<< ' //print_matrices(); //<<<<<<<<<<<<'
- FI;
- GEN<< ' //' end of COORDINATE;
- LAST #generate_coordination_class $nesting_depth +:= -1/
- .>;;
-
- ----------------------------------------------------------------------------------
- <. operation: SHARE_ALL
- /GEN<<;
- GEN<< ' //' SHARE ALL operation;
- GEN<< ' create_matrices();'/,
-
- shared_events: $shared_events,
-
- host_list: (. (* (. (<. comp: $host_name .> /$source_name:= #IMPLODE($host_name '_source')/ !
- <. var: $host_name .> /$source_name:= $host_name/)
- -- single host
- /$hosts ++:= <. $host_name: T .>;
- GEN<<;
- IF $source_name <> $host_name ->
- GEN<< ' int' $source_name ';// shareholder';
- GEN<< ' // find host event' $host_name;
- GEN<< ' for(int i = 0; i < Stack.size(); i++){';
- GEN<< @' if( Stack[i]->name == Event_' $host_name '){';
- GEN<< ' ' $source_name '= i; break; } }';
- FI;
- GEN<< ' // lists of shared events for ' $host_name;
- FORALL $e IN $shared_events DO
- GEN<< @' vector<int> ' $host_name '_' $e '_list;'
- OD;/
- .)
- *)
- .),
-
- host_list: /GEN<<;
- GEN<< ' //' create lists of shared events;
- GEN<< ' for(int i = 0; i < len; i++){'/
-
- (. (* (. (<. comp: $host_name .> /$source_name:= #IMPLODE($host_name '_source')/ !
- <. var: $host_name .> /$source_name:= $host_name/)
- -- single host
- /GEN<< ' if(in_matrix[i * len +' $source_name ']){';
- FORALL $e IN $shared_events DO
- GEN<< @' if( Stack[i]->name == Event_' $e ' ){';
- GEN<< ' //' make sure this is fresh event not yet shared;
- GEN<< ' int found = 0;';
- GEN<< ' for(vector<int>:: iterator s = '
- @$host_name '_' $e '_list.begin();';
- GEN<< @ ' s != ' $host_name '_' $e
- '_list.end(); s++){';
- GEN<< ' if((found = eq_matrix[i * len + *s])) break;';
- GEN<< ' }';
- GEN<< @' if(!found) ' $host_name '_' $e '_list.push_back(i);';
- GEN<< ' }'
- OD;
- GEN<< ' };'/
- .)
- *)
- .)
- /GEN<< ' } //' end for create lists of shared events;
- $single_host:= $host_name/,
-
- shared_events: /GEN<<;
- GEN<< ' //' check that selected lists are of the same length;
- GEN<< ' int len_to_compare;'/
-
- <* $event_name: $x
- /GEN<< @' len_to_compare = ' $single_host '_' $event_name '_list.size();';
- FORALL $h IN $hosts DO
- IF $h <> $single_host ->
- GEN<< @' if(' $h '_' $event_name '_list.size() != len_to_compare) '
- @ throw failed ';'
- FI
- OD/
- *>,
-
- host_list: /GEN<<;
- GEN<< ' //' sort the lists/
-
- (. (* (. (<. comp: $host_name .> /$source_name:= #IMPLODE($host_name '_source')/ !
- <. var: $host_name .> /$source_name:= $host_name/)
- -- single host
- /FORALL $e IN $shared_events DO
- GEN<< @' sort_events(' $host_name '_' $e '_list);';
- OD/
- .)
- *)
- .),
-
- shared_events: /GEN<<;
- GEN<< ' //' do the SHARE ALL/
-
- <* $event_name: $x
- /GEN<< @' len_to_compare = ' $single_host '_' $event_name '_list.size();';
- GEN<< ' for(int i = 0; i < len_to_compare; i++){';
- FORALL $h IN $hosts DO
- IF $h <> $single_host ->
- GEN<< @' make_equality_complete(' $single_host '_' $event_name '_list[i], '
- $h '_' $event_name '_list[i]);'
- FI
- OD;
- GEN<< ' }'/
- *>
-
- .>
- /GEN<< ;
- IF LAST #generate_coordination_class $nesting_depth < 2 ->
- GEN<< ' create_matrices(); //' to check for axiom violation;
- GEN<< ' //print_matrices(); //<<<<<<<<<<<<'
- FI;
- GEN<< ' //' end of SHARE ALL;
- LAST #generate_coordination_class $nesting_depth +:= -1/
- ;;
- $a /PRINT (. generation for $a not yet implemented .)/
- ##
- #generate_schema_class
- -- from $model.elt_list
- /GEN<< '//----' #class_counter() '----';
- GEN<< class @ 'SCHEMA_' LAST #AG $model.schema ': public Composite_producer {';
- GEN<< 'public:' '//' constructor;
- GEN<< ' ' @ 'SCHEMA_' LAST #AG $model.schema '(): Composite_producer(Event_'
- LAST #AG $model.schema '){';
- GEN<< ' target_event = Schema_node;';
- GEN<< ' element = new Event_producer_ref[ element_count ='
- #LEN(LAST #AG $model.elt_list) '];';
- $element_count:= 0 /
- (. (* ( <. ROOT: $root_name .>
- /GEN<< ' element[' $element_count
- @ ']= new Composite_secondary_producer(Event_' $root_name ');';
- $element_count +:= 1 / !
-
- ( <. COORDINATE: $work .> ! <. SHARE_ALL: $work .> )
- /GEN<< ' element[' $element_count
- @ ']= new ' $work '_ob(Event_' $work ');';
- $element_count +:= 1 / !
-
- $any -- other composition ops here
- )
- *)
- .)
- /GEN<< ' }';
- GEN<< '};//' end class @ 'SCHEMA_' LAST #AG $model.schema;
- GEN<< /
- ##
- #generate_harvest_calls
-
- (. /GEN<< ' //' harvesting traces for composite events/
- (* $comp_name
- /$t:= #class_counter();
- GEN<< ' ' LAST #AG $new_composites.$comp_name.work_name @ 'temp_' $t
- '; temp_' $t '.harvest();'/
- *)
- .)
- ##
- #harvest_roots
- -- works on $new_root_table
- /GEN<< ' //' harvesting traces for ROOT events/
- <* $event_name:
- <. work_name: $work_name,
- rule_type: ( composite !
- ROOT
- /$t:= #class_counter();
- GEN<< ' ' $work_name
- @ 'temp_' $t '; temp_' $t '.harvest();'/ )
- .>
- *>
- ##
- #harvest_main_schema
- /GEN<< ' //' harvesting traces for main schema;
- $t:= #class_counter();
- GEN<< ' ' @ 'SCHEMA_' LAST #AG $model.schema
- ' temp_' $t '; temp_' $t '.harvest();';
-
- -- generate text file with event traces
- GEN<< @ ' temp_' $t '.output_JSON();';
- GEN<< ' gen_end = clock();';
- GEN<< @ ' temp_' $t '.show_traces();'/
- ##
- --------------------------------------------------
- #class_counter
- /LAST #AG $class_counter +:=1;
- RETURN COPY(LAST #AG $class_counter)/
- ##
|