help-bison
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: opinion on back end architecture


From: Hans Aberg
Subject: Re: opinion on back end architecture
Date: Sat, 22 Nov 2003 01:46:16 +0100

(Please keep the Help-Bison cc, as more can then help.)
At 15:41 -0500 2003/11/21, Urdaneta, Alfonso E (N-Summitt Technologies) wrote:
>Sorry to bug you guys directly, but I was wondering if you had an opinion
>either way on an architecture question I had posted to comp.compilers.
>Basically its about the code that sits behind the parser, and how it
>should be set up.
>
>http://groups.google.com/groups?dq=&start=75&hl=en&lr=&ie=UTF-8&oe=UTF-8&group=
>comp.compilers&selm=03-10-057%40comp.compilers

This is:
>>>>
This is more of a general architecture question, rather than one
specific to compilers.  Basically I'm trying to find out what is
preferred practice for the code that handles the output from the
parser, and its general code structure.

Any language has some fundamental building blocks that can occur in
all sorts of statement, such as integers, quoted character strings,
etc.

Is it common practice to have a central repository into which all
these values go to, and the specific handlers then cherrypick from it
the data they need, or is preferable to have a base class which has
interfaces for all the primitives, and subclass this for specific
statements ?

Say we have 3 statement types, A, B, C, which use say, integers.

Option 1.

 parser finds an int, stick it in common int pool
 parser realizes last statement is of type A, B or C, and calls the
the specific handler for that statememnt, which then pulls the
integers from the common pool to do their thing

Option 2.

There is a handler for A B and C, all of which implement the function
"handleInteger".

  parser realizes its parsing a statement of type B, sets the overall
handler to be of type "B".  when an integer is cound,
B->handleInteger(val) is called.  likewise for all the others.


Which of those two ways is this type of thing done - or is there
another alternate ?  Option 2 seems cleaner, but it also seems like it
will require a lot more overhead.

I hope this question makes sense to you guys, I can't think of another
way to phrase it.
<<<<

I program in C++, and I do not use Bison statement types, because one must
tweak it in order to get around the %union limitation of not using C++
union with type having non-trivial constructors.

Instead I use a polymorphic (virtual) hierarchy. Then every statement type
will be represented by a C++ class in that hierarchy.

In that setting, the lexer can either produce an object in the polymorphic
hierarchy, or a value outside it, which is converted to a value n the
polymorphic hierarchy explicitly by the rule action.

So you can do both, which I do. In addition, I use a hybrid type:

class semantic_type {
public:
  long number_;
  std::string text_;
  mli::object object_;

  semantic_type() : number_(0) {}
};

#define YYSTYPE semantic_type

By this method, I can choose when to convert a number_ or a text_ into an
object_, depending on the situation. It turns out to be useful to sometimes
let the lexer return a combination of these values. For example, number_
could be a object type of the object_ in a lookup table with the lookup
name text_. I then use this to make convenient definitions in my grammar.

  Hans Aberg






reply via email to

[Prev in Thread] Current Thread [Next in Thread]