79 lines
2.4 KiB
HTML
79 lines
2.4 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
|
<HTML>
|
|
<HEAD>
|
|
<META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.9">
|
|
<TITLE>Lex and YACC primer/HOWTO: Making a Parser in C++</TITLE>
|
|
<LINK HREF="Lex-YACC-HOWTO-6.html" REL=next>
|
|
<LINK HREF="Lex-YACC-HOWTO-4.html" REL=previous>
|
|
<LINK HREF="Lex-YACC-HOWTO.html#toc5" REL=contents>
|
|
</HEAD>
|
|
<BODY>
|
|
<A HREF="Lex-YACC-HOWTO-6.html">Next</A>
|
|
<A HREF="Lex-YACC-HOWTO-4.html">Previous</A>
|
|
<A HREF="Lex-YACC-HOWTO.html#toc5">Contents</A>
|
|
<HR>
|
|
<H2><A NAME="s5">5. Making a Parser in C++</A></H2>
|
|
|
|
<P>Although Lex and YACC predate C++, it is possible to generate a C++ parser.
|
|
While Flex includes an option to generate a C++ lexer, we won't be using
|
|
that, as YACC doesn't know how to deal with it directly.
|
|
<P>My preferred way to make a C++ parser is to have Lex generate a plain C
|
|
file, and to let YACC generate C++ code. When you then link your
|
|
application, you may run into some problems because the C++ code by default
|
|
won't be able to find C functions, unless you've told it that those
|
|
functions are extern "C".
|
|
<P>To do so, make a C header in YACC like this:
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
extern "C"
|
|
{
|
|
int yyparse(void);
|
|
int yylex(void);
|
|
int yywrap()
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
}
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
<P>If you want to declare or change yydebug, you must now do it like this:
|
|
<P>
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
extern int yydebug;
|
|
|
|
main()
|
|
{
|
|
yydebug=1;
|
|
yyparse();
|
|
}
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
<P>This is because C++'s One Definition Rule, which disallows multiple
|
|
definitions of yydebug.
|
|
<P>You may also find that you need to repeat the #define of YYSTYPE in your Lex
|
|
file, because of C++'s stricter type checking.
|
|
<P>To compile, do something like this:
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
lex bindconfig2.l
|
|
yacc --verbose --debug -d bindconfig2.y -o bindconfig2.cc
|
|
cc -c lex.yy.c -o lex.yy.o
|
|
c++ lex.yy.o bindconfig2.cc -o bindconfig2
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
<P>Because of the -o statement, y.tab.h is now called bindconfig2.cc.h, so take
|
|
that into account.
|
|
<P>To summarize: don't bother to compile your Lexer in C++, keep it in C. Make
|
|
your Parser in C++ and explain your compiler that some functions are C
|
|
functions with extern "C" statements.
|
|
<P>
|
|
<HR>
|
|
<A HREF="Lex-YACC-HOWTO-6.html">Next</A>
|
|
<A HREF="Lex-YACC-HOWTO-4.html">Previous</A>
|
|
<A HREF="Lex-YACC-HOWTO.html#toc5">Contents</A>
|
|
</BODY>
|
|
</HTML>
|