Home | History | Annotate | Download | only in tweak
      1 /** Convert the simple input to be java code; wrap in a class,
      2  *  convert method with "public void", add decls.  This shows how to insert
      3  *  extra text into a stream of tokens and how to replace a token
      4  *  with some text.  Calling toString() on the TokenRewriteStream
      5  *  in Main will print out the original input stream.
      6  *
      7  *  Note that you can do the instructions in any order as the
      8  *  rewrite instructions just get queued up and executed upon toString().
      9  */
     10 grammar T;
     11 options { language = Perl5; }
     12 
     13 program
     14     :   method+
     15         {
     16         $input->insert_before($input->LT(1), "public class Wrapper {\n");
     17         // note the reference to the last token matched for method:
     18         $input->insert_after($method.stop, "\n}\n");
     19         }
     20     ;
     21 
     22 method
     23     :   m='method' ID '(' ')' body
     24         { $input->replace($m, "public void"); }
     25     ;
     26 
     27 body
     28 scope {
     29     // decls is on body's local variable stack but is visible to
     30     // any rule that body calls such as stat.  From other rules
     31     // it is referenced as $body::decls
     32     // From within rule body, you can use $decls shorthand
     33     decls;
     34 }
     35 @init {
     36     $body::decls = [];
     37 }
     38     :   lcurly='{' stat* '}'
     39         {
     40         // dump declarations for all identifiers seen in statement list
     41         foreach my $id ($body::decls) {
     42             $tokens->insert_after($lcurly, "\nint $id;");
     43         }
     44         }
     45     ;
     46 
     47 stat:   ID '=' expr ';' { $body::decls->add($ID.text); } // track left-hand-sides
     48     ;
     49 
     50 expr:   mul ('+' mul)*
     51     ;
     52 
     53 mul :   atom ('*' atom)*
     54     ;
     55 
     56 atom:   ID
     57     |   INT
     58     ;
     59 
     60 ID  :   ('a'..'z'|'A'..'Z')+ ;
     61 
     62 INT :   ('0'..'9')+ ;
     63 
     64 WS  :   (' '|'\t'|'\n')+ { $channel = $self->HIDDEN; }
     65     ;
     66