1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** Convert the simple input to be java code; wrap in a class,
2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  convert method with "public void", add decls.  This shows how to insert
3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  extra text into a stream of tokens and how to replace a token
4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  with some text.  Calling toString() on the TokenRewriteStream
5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  in Main will print out the original input stream.
6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *
7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  Note that you can do the instructions in any order as the
8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  rewrite instructions just get queued up and executed upon toString().
9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */
10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvergrammar T;
11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruveroptions { language = Perl5; }
12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverprogram
14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    :   method+
15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $input->insert_before($input->LT(1), "public class Wrapper {\n");
17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // note the reference to the last token matched for method:
18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $input->insert_after($method.stop, "\n}\n");
19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ;
21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermethod
23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    :   m='method' ID '(' ')' body
24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        { $input->replace($m, "public void"); }
25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ;
26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverbody
28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverscope {
29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // decls is on body's local variable stack but is visible to
30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // any rule that body calls such as stat.  From other rules
31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // it is referenced as $body::decls
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // From within rule body, you can use $decls shorthand
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    decls;
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver@init {
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    $body::decls = [];
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    :   lcurly='{' stat* '}'
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // dump declarations for all identifiers seen in statement list
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        foreach my $id ($body::decls) {
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            $tokens->insert_after($lcurly, "\nint $id;");
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ;
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstat:   ID '=' expr ';' { $body::decls->add($ID.text); } // track left-hand-sides
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ;
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverexpr:   mul ('+' mul)*
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ;
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermul :   atom ('*' atom)*
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ;
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruveratom:   ID
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    |   INT
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ;
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
60324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverID  :   ('a'..'z'|'A'..'Z')+ ;
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
62324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverINT :   ('0'..'9')+ ;
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
64324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverWS  :   (' '|'\t'|'\n')+ { $channel = $self->HIDDEN; }
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ;
66