5

after upgrading from bison 2.7 to 3.0 I changed the following two lines in my parser definition file (.yy)

-------old--------
%define parser_class_name smathparser
%name-prefix = "imath"
-------new--------
%define api.prefix {imath}
%define parser_class_name {smathparser}
-------------------

and the result is that I get the following compiler errors when compiling the parser (!) file (compiling the lexer file gives no errors even though it uses yylval heavily):

error: ‘yylval’ was not declared in this scope
error: ‘yylloc’ was not declared in this scope

I searched everywhere I could think of but I couldn't see where yylval and yylloc are being defined. Have they been renamed? Deprecated? Why do they work in the lexer but not in the parser????

For clarification: I am actually using yylval and yylloc in the code of the parser.

jrheinlaender
  • 59
  • 1
  • 6

2 Answers2

9

yylval and yylloc are set in the lexer, not in the parser. Traditionally, these are global variables, but in a "pure" (re-entrant) parser, they are internal to the parser, and their addresses are passed to the scanner as arguments. C++ parsers are always pure.

Since 3.0, these values are no longer independent variables in the parser; rather, they are part of a class representing a symbol. That change doesn't affect the scanner, since it still receives the same pointers as arguments, but it makes the values inaccessible by name to parser actions.

Clearly, that incompatibility should be documented somewhere, but I haven't found where.

Nonetheless, it's worth noting that you rarely need to refer to the semantic value and location of the lookahead token in a parser action, although doing so has been supported since time immemorial and continues to work in C parsers, and even in GLR parsers. I'm sure you have your reasons, and while I'm curious as to what they are, you are under no obligation to reveal them. Examination of the C++ skeleton code suggests that you should be able to use yyla.value and yyla.location instead of yylval and yylloc, but that's not documented so there are no guarantees.

If we're lucky, Akim Demaille will come by and answer this question properly. Personally, I use the C interface, even with C++; old habits die hard.

rici
  • 234,347
  • 28
  • 237
  • 341
  • Thanks, that worked! I'm aware that it isn't very clean programming to use yyla in the parser, but this is in code that has been stable for a long time and I don't really want to touch it any more than necessary. I was forced to upgrade to bison 3.0 because Ubuntu has gone that way. – jrheinlaender May 16 '14 at 04:07
3

In a .yy file of ours that was similarly affected by the upgrade to bison 3.0, I replaced yylloc with @$.

Fabio Somenzi
  • 193
  • 3
  • 8
  • Does that have the same semantics, though? `yylloc` should be the location of the current lookahead token, while `@$` in an action is the merged location of the total production (created with the macro `YYLLOC_DEFAULT`. In bison 2, the variable which `@$` was translated into was `yyloc` (with one `l`); in 3.0 it has become `yylhs.location`. But afaik, that's a different value from `yylloc` – rici May 17 '14 at 04:09
  • Not the same semantics, but in the `.yy` file I was referring to, `yylloc` was used in a production for an identifier in case the identifier was undefined. Changing `yylloc` to `@$` had no effect on the location reported in case that error was triggered. On the positive side, the change works with bison 2.4, 2.7, and 3.0. On the negantive side, as you point out, one has to check whether the replacement is valid in context. – Fabio Somenzi May 18 '14 at 03:23
  • Hard to tell without knowing (a lot) more but it seems like the use of `yylloc` was actually incorrect in the original `.yy` file, and perhaps worked because reducing the production in question could happen without the need for a lookahead token, in which case `yylloc`'s value would be technically invalid but in practice the location of the last token in the RHS. In that case, the correct thing to use would be `@N`, where `N` is the length of the RHS: probably `@1`. For any production whose RHS has length one, `@1` and `@$` will have the same value with the default location merge macro. – rici May 18 '14 at 03:32