Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I'm in the process of creating a compiler for a relatively simple language using Flex and Bison on Windows. However the compiler is telling me thatthe functions yyerror and yyparse weren't declared in the right scope. After some reading I found out that the problem is apparently conflicting C and C++ linkage (I'm using g++ as I'm trying to build an abstract syntax tree). Code excerpts below.
monty.y:
extern "C" {
int yyparse();
int yylex(void);
void yyerror(char *s){}
int yywrap(void){return 1;}
#include <stdio.h>
#include <string.h>
#include "ast\ast.h"
using namespace std;
Program* root;
//extern int yyparse();
main() {
yyparse();
monty.l:
#include <stdlib.h>
#include "ast/ast.h"
#include "y.tab.h"
"do" { puts("DO"); return DO; }
"else" { puts("ELSE"); return ELSE; }
"end" { puts("END"); return END; }
"if" { puts("IF"); return IF; }
etc...
int main(void)
yyparse();
return 0;
Any help or enlightenment as to the source of these errors would be greatly appreciated :)
The code in a
.y
file that's enclosed in
%{ ... }%
is copied verbatim to the top of the generated parser file
before the definitions
of the autogenerated functions like
yyparse
. As a result, the code that you've written, including the definition of
main
and the call to
yyparse
, appear before any of those functions are declared or defined. This may be the source of your error.
Remember that the generated parser file doesn't have to contain
main
. In fact, you might want to consider creating a separate C++ source file that contains
main
. You'd then have that file include the autogenerated header so that it sees the declaration of
yyparse
.
Additionally, if you are trying to write C++ code for this program, note that the
main
function you declared in the bison source file is not valid C++ because it doesn't have a return type declared. All C++
main
functions must explicitly return an
int
.
Also notice that you have two main functions, one in the lexer file and one in the parser file, which will cause problems for you going forward. Factoring out your
main
function into its own separate file that then includes the lexer and parser header files will resolve this issue.
Finally, note that if you are indeed generating C++ code, there's no need to put
void
in the parameter list to
main
. C++ assumes that an empty parameter list means "takes no parameters" and there's no need to state otherwise.
–
There is no need to declare
yyerror
and
yyparse
as
extern "C"
if you compile your flex file as C++.
In fact, there is no need to declare
yyerror
and
yyparse
as
extern "C"
unless you refer to them from a different module
. You do refer to
yyparse
in the
main()
in your
flex
file, but you also have a
main()
in your bison file, and you only need one
main()
. There is no indication that you call
yyerror()
from your flex file, and in general it is not a good idea IMHO. But if you do call
yyerror
and
yyparse
from your flex file, you will need to declare them in that file. And if you
are
compiling the flex-generated scanner as C++, then the declaration in your bison file as
extern "C"
will actually create a problem rather than solving one.
In short:
extern "C"
is rarely the correct solution to any bison/flex problem.
flex-generated scanners can be compiled with a C++ compiler even if they are generated as C files. The same is true of bison-generated parsers, although there are more use cases in which generating a C++ parser is useful.
You will make your life easier if you compile both your scanner and your parser with the same language.
–
–
–
–
–
Thanks for contributing an answer to Stack Overflow!
-
Please be sure to
answer the question
. Provide details and share your research!
But
avoid
…
-
Asking for help, clarification, or responding to other answers.
-
Making statements based on opinion; back them up with references or personal experience.
To learn more, see our
tips on writing great answers
.