[Top][All Lists]

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

Re: Multitype support in bison

From: Laurence Finston
Subject: Re: Multitype support in bison
Date: Sun, 14 Oct 2007 18:24:38 +0200 (CEST)

On Sun, 14 Oct 2007, Ilyes Gouta wrote:

> Well the problem is that the generic token IDENTIFIER can refer to a
> variable which can hold an integer as well as a float (depending on
> its type). This is the source of my worries. How can I have a separate
> set of rules for ints and floats knowing that only one set would
> handle IDENTIFIER. It can't exist in the second set since it will
> cause ambiguity.

> Both unary_iexpr and unary_fexpr are able to process IDENTIFIER (i.e
> ambiguity). And actually, I'll have to call either ivalue($1) or
> fvalue($2) depending on the nature of the said IDENTIFIER to get its
> value and let bison push it in the evaluation stack.

> I think, I can't have two != sets of rules. As Hans Aberg said, I'll
> have to do type-checking within the actions...
> Any clues?

Any type checking you do will have to be in the actions.  If each of your 
symbols can only have a semantic value of a single type, this makes things 

There are various ways you can go about solving this problem.  I've
solved a similar problem using a technique I call "faking a token".
If you search the archives of this mailing list, you will find that
I've mentioned it before.  It is a way of passing information from
actions to `yyparse', which isn't always easy.

The tokens aren't really fake, they are just as real as any other
tokens.  I have a non-terminal symbol called `variable'.  The semantic
value of `variable' is `void*' and it points to an object whose type
is `Id_Map_Entry_Type'.  This class in turn contains a data member of
type `void*' which points to an object of some type and a data member
of an integral type which identifies the type.  When the rule with
`variable' on the left-hand 
side, namely "variable: tag suffix", is reduced, the action
examines the `Id_Map_Entry_Type' object and determines what the `type'
is.  It then pushes a token onto a stack which is available to
`yylex'.  When the latter is called, it 
first examines to see whether there are any tokens in this stack.  If
there are, it pops the top one and returns it to `yyparse'
immediately, without trying to read from its normal source of input.

Say this is the input:

point p; 
p := (1, 2, 3);

When `p' is read, the rule "variable: tag suffix"' is eventually 
reduced.  The action examines the `Id_Map_Entry_Type' object to which
it refers, determines that it is a point, and pushes the token `POINT'
(which is really a number defined by a preprocessor macro by Bison)
onto the stack.  `yylex' then returns `POINT' to `yyparse' so the next 
rule to be reduced will be "point_variable: variable POINT".  This is
the only way the token `POINT' can ever reach `yyparse'.

There are similar rules for variables of other types, e.g.,

numeric_variable: variable NUMERIC
                | variable UNDECLARED

ulong_long_variable: variable ULONG_LONG

transform_variable: variable TRANSFORM

picture_variable: variable PICTURE
                | LAST picture_vector_variable

point_variable: variable POINT

focus_variable: variable FOCUS

macro_variable: variable MACRO
              | LAST macro_vector_variable

path_variable: variable PATH

ellipse_variable: variable ELLIPSE

circle_variable: variable CIRCLE


Please note that an undeclared variable is automatically a `numeric'.
This makes it possible to use numeric variables without declaring them 
first.  Please also note that I wrote my version of `yylex' from
scratch rather than using Flex.  However, it ought to be possible
using Flex, too.

The full story is more complicated, but that's the main idea.  It's
just one approach;  there are others.

If you want to look at the actual code, it's all here:

The description of the grammar generated by Bison is in the file
`parser.output'.  The definition of `yylex' is in `scan.web',
and the input code for Bison is in the files with the extension `.w'.
`parser.w' would be the place to start.


reply via email to

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