简体   繁体   English

在Qt中使用Flex和Bison

[英]Using Flex and Bison with Qt

I am trying to use flex and bison with qt.There many web resource about it.They all use the QMAKE_EXTRA_COMPILERS to add precompile.But I always get the LNK2019 of the yyerror and yywrap when I compile the code.My code was follow: 我正在尝试将flex和bison与qt一起使用,关于Web的资源很多,它们都使用QMAKE_EXTRA_COMPILERS添加预编译,但是我总是在编译代码时得到yyerror和yywrap的LNK2019,我的代码如下:

pro file 专业档案

CONFIG += console
CONFIG -= app_bundle

LIBS += -lfl

FLEXSOURCES = lexer.l
BISONSOURCES = parser.y

OTHER_FILES +=  \
    $$FLEXSOURCES \
    $$BISONSOURCES

QT += core gui script

SOURCES += main.cpp

TEMPLATE = app

bisonsource.input = BISONSOURCES
bisonsource.output = ${QMAKE_FILE_BASE}.cpp
bisonsource.commands = bison -d --defines=${QMAKE_FILE_BASE}.h -o ${QMAKE_FILE_BASE}.cpp ${QMAKE_FILE_IN}
bisonsource.variable_out = SOURCES
bisonsource.name = Bison Sources ${QMAKE_FILE_IN}
bisonsource.CONFIG += target_predeps

QMAKE_EXTRA_COMPILERS += bisonsource

bisonheader.input = BISONSOURCES
bisonheader.output = ${QMAKE_FILE_BASE}.h
bisonheader.commands = @true
bisonheader.variable_out = HEADERS
bisonheader.name = Bison Headers ${QMAKE_FILE_IN}
bisonheader.CONFIG += target_predeps no_link

QMAKE_EXTRA_COMPILERS += bisonheader

flexsource.input = FLEXSOURCES
flexsource.output = ${QMAKE_FILE_BASE}.cpp
flexsource.commands = flex --header-file=${QMAKE_FILE_BASE}.h -o ${QMAKE_FILE_BASE}.cpp ${QMAKE_FILE_IN}
flexsource.variable_out = SOURCES
flexsource.name = Flex Sources ${QMAKE_FILE_IN}
flexsource.CONFIG += target_predeps

QMAKE_EXTRA_COMPILERS += flexsource

flexheader.input = FLEXSOURCES
flexheader.output = ${QMAKE_FILE_BASE}.h
flexheader.commands = @true
flexheader.variable_out = HEADERS
flexheader.name = Flex Headers ${QMAKE_FILE_IN}
flexheader.CONFIG += target_predeps no_link

QMAKE_EXTRA_COMPILERS += flexheader

lexer.l lexer.l

%{

#include "parser.h"

extern void yyerror(const char *s);

%}

%%

"+"  { return ADD; }

"-"   { return SUB; }

"*"  { return MUL; }

"/"   { return DIV; }

"|"     { return ABS; }

"("     { return OP; }

")"     { return CP; }

[0-9]+    { yylval = atoi(yytext); return NUMBER; }



\n      { return EOL; }

"//".*

[ \t]   { /* ignore white space */ }

.      { yyerror("Mystery character\n"); }

%%

parser.y 解析器

%{

#include <stdio.h>

// yylex is a function generated by Flex and we must tell to Bison that it is
// defined in other place.
extern int yylex(void);

// Bison uses the yyerror function for informing us when a parsing error has
// occurred.
void yyerror(const char *s);

%}



/* declare tokens*/

%token NUMBER

%token ADD SUB MUL DIV ABS

%token OP CP

%token EOL



%%



calclist: /*nothing */

 | calclist exp EOL { printf("= %d\n>", $2); }

 | calclist EOL { printf("> "); }/* blank line or a comment */

 ;



exp: factor

 | exp ADD exp { $$ = $1 + $3; }

 | exp SUB factor { $$ = $1 - $3; }

 | exp ABS factor { $$ = $1 | $3; }

 ;



factor: term

 | factor MUL term { $$ = $1 * $3; }

 | factor DIV term { $$ = $1 / $3; }

 ;



term: NUMBER

 | ABS term { $$ = $2 >= 0? $2 : - $2; }

 | OP exp CP { $$ = $2; }

 ;

%%

void yyerror(char *s)
{

  fprintf(stderr, "error: %s\n", s);

}

main.cpp main.cpp

#include <QtCore>

// This header is generated by Flex.
#include "lexer.h"

// This header is generated by bison.
#include "parser.h"

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);

    QString str("1+1");

    // Insert the string into the input stream.
    YY_BUFFER_STATE bufferState = yy_scan_string(str.toUtf8().constData());

    // Parse the string.
    yyparse();

    // flush the input stream.
    yy_delete_buffer(bufferState);

    return app.exec();
}

yywrap is undefined because you never defined it. yywrap是未定义的,因为您从未定义它。 You must define it, or tell flex that it is not needed. 您必须定义它,或告诉flex不需要它。 I assume you don't need it, so you should add 我认为您不需要它,因此您应该添加

%option noyywrap

to your flex input file ( lexer.l ). 到您的flex输入文件( lexer.l )。 (It goes before the first %% but not inside the prolog (the part surrounded by %{ and %} .) (See the flex manual for more information.) (它在第一个%%之前,但不在序言内部(被%{%}包围的部分%} 。(有关更多信息,请参见flex手册 。)

yyerror is not defined (in the lexer file) because it is defined in the parser file, and you are compiling your parser as a C++ program, while you compile your lexer as a C program. yyerror未定义(在lexer文件中),因为它是在解析器文件中定义的,并且您正在将解析器编译为C ++程序,而将词法分析器编译为C程序。

You don't use C++ in either file, so you could compile both as C. Or you could compile both as C++. 您在这两个文件中都不使用C ++,因此可以将两者都编译为C。也可以将两者都编译为C ++。 Or you could declare yyerror as extern "C" . 或者,您可以将yyerror声明为extern "C" If you compile the parser as a C program, then you'll need to declare yyparse as extern "C" in main.cpp , which uses QT and thus must be C++. 如果将解析器编译为C程序,则需要在main.cpp中将yyparse声明为extern "C" ,它使用QT,因此必须为C ++。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM