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 easier. 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 etc. 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: http://cvs.savannah.gnu.org/viewvc/3dldf/3dldf/Group/CWEB/ 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. Laurence _______________________________________________ help-bison@gnu.org http://lists.gnu.org/mailman/listinfo/help-bison