I'm attempting to create a reentrant parser using C++ with flex and bison. I'm also using a driver class Driver
. I'm getting the error 'yyscanner' : undeclared identifier
on the lex side of things. I think it has something to do with the reentrant option in flex, which is strange since I would have assumed that driver
would have been used in it's place, since I declare yylex
as yylex(Driver& driver)
in driver.h
. Is there anything I've done wrong in my code below to get this error message? Any help would be much appreciated.
parser.y
%require "3.2"
%define parse.error verbose
%locations
%param { Driver& driver }
%language "c++"
%define api.value.type variant
%code requires {
class Driver;
}
%code {
#include "driver.h"
}
...
lexer.l
%option noyywrap noinput nounput
%option nodefault
%option nounistd
%option reentrant
%{
#include <iostream>
#include <string>
#include "driver.h"
#include "parser.tab.h"
%}
%%
%{
yy::location& loc = driver.location;
%}
...
driver.h
#ifndef DRIVER_HH
#include "parser.tab.h"
#define YY_DECL \
int yylex(Driver& driver)
YY_DECL;
class Driver
{
public:
Driver() {}
yy::location location;
};
#endif // ! DRIVER_HH
If you generate a reentrant scanner, you must define its prototype to include a parameter named yyscanner
of type yyscan_t
. And you need to call the scanner with that argument. You cannot substitute some type you have defined for the yyscan_t
argument, because your type does not include the data members which the flex-generated scanner uses. And you must use the name yyscanner
because that's how the code generated by Flex references the data members.
If you want a yylex
which only needs one argument, the "official" way to do that is to put your data members (or a pointer to them) into the "extra data" in the yyscan_t
. But it might be easier to just use two arguments.