Hi all,

I'm currently working on a project to revamp an existing code generation system 
my team uses and add some new features.  The generator takes a set of 
pseudo-class/struct definitions like

class foo
{
      Int X;
      SomeClass Y;
      map<int,int> Z;
};

And generates an output C++ class with a bunch  of decoration.

class foo
{
public:
        int getX() const { return mX; }
        void setX(int val) { mX = val; }

        SomeClass &getY() { return mY; }

        Map<int,int> &getZ() { return mZ; }

Private:
 Int X;
 SomeClass Y;
 map<int,int> Z;
};

(There's a lot more to the specification, but this is good enough to 
demonstrate my issues).

One of our goals is to support a lot more than C++, and to allow people to 
override the generation as necessary to fit into their projects.  ANTLR + 
StringTemplates seems to suit our needs perfectly.  Our old model used 
flex/bison, a custom tree of classes (since classes can have inner classes, and 
we support namespaces), and a gnarly set of hand-written C++ output code.  Yuck.

So I've spent the past few weeks getting into ANTRL, reading the manual, 
reading the reference, trying out the samples, building samples, toy languages 
etc.  I'm now in the process of prototyping out our new tool, but I've run into 
a dilemma on the overall structure.

What I'd like to do is parse everything into an AST, then build a tree walker 
that outputs templates (and maybe another walker to do some error 
verification).  But what I can't figure out is how you separate the MVC model 
parts using a tree walker and templates.  I want to have a main template 
interface such that the "big items" (class, member, etc) are put out through 
there, and a subtemplate interface for overriding something like C++.  In that 
way, if I want to change the type of "map" to be "custommap" I just need to 
change the template that prints out a map type.  What I don't get though is 
that with a tree walker you get one stab at outputting text.  So if I have a 
template like:

class $className$
{
public:
        $members$
};

I can see how the top section gets printed out:

class : ^(CLASS n=SYMBOL m=members*) - > classTemplate(name={$n.text}, 
members={$m}) ;
member : ^(int n=SYMBOL) -> intMemberTemplate(name={$n.text}) ;
  | ^(t=SYMBOL n=SYMBOL) -> classMemberTemplate(name={$n.text}, type={$t}) ;
        ;

Where intMemberTemplate and classMemberTemplate print out the getter/setter 
funcs from above.

What I don't see how to do is have two sections where the class walks through 
the members.  It goes through them once, emits their templates once, and moves 
on.  To generate the C++ class above, I need two passes - one to generate the 
getters/setters, one to do the variable declarations.  I could do it in one 
pass with lots of public/private keywords, but the generated code is less 
readable.  I could duplicate the tree, but then I'm forcing view structure into 
the model, which seems to go against the whole ST philosophy.  I could also 
create a "member" object and use its attributes in the template, but I guess 
that seems a little less clean because then I'm really walking through some 
other data structure instead of using the tree walker.

One other reason I want to use the tree walker to print out the various 
getters/setters and declarations is that it has built in context as to what 
each member is.  If I just have something like

private:
$members:declVar()$
};

Then the template "declVar" either needs to have a bunch of if..else statements 
to split up the member type and print out the right thing, or I need to do 
something like have a Member.toString() function to do the dirty work of 
formatting the declaration.  That of course means potentially putting in view 
code in the model, which I'd really like to avoid.

So bottom line:  am I leaning to far in the "do everything in the tree walker" 
direction?  Has anyone had a problem where one input can generate several 
templates, and each template might have several different variations depending 
on the input?    I feel like I should have seen this done somewhere, but I 
looked through a lot of examples and didn't see exactly what I wanted.

Any advice here is appreciated.

Thanks
Ryan





--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"il-antlr-interest" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/il-antlr-interest?hl=en
-~----------~----~----~----~------~----~------~--~---

List: http://www.antlr.org/mailman/listinfo/antlr-interest
Unsubscribe: 
http://www.antlr.org/mailman/options/antlr-interest/your-email-address

Reply via email to