yyparse()的未解析外部符号 [英] unresolved external symbol for yyparse()
问题描述
我的main.cpp看起来像这样:
My main.cpp looks like this:
#include <assert.h>
#include <fstream>
#include <iostream>
#include "astgen.h"
#include "astexec.h"
extern int yyparse();
extern FILE *yyin;
int main()
{
//yydebug = 0;
struct AstElement *a = 0;
FILE *fp ;
fopen_s(&fp,"example.txt","r");
//std::cout<<fp;
if (fp==NULL)
{
std::cout<<"error";
}
yyin=fp;
yyparse();
assert(a);
struct ExecEnviron* e = createEnv();
execAst(e, a);
freeEnv(e);
/* TODO: destroy the AST */
}
当我尝试编译它时,出现错误:main.obj:错误LNK2019: unresolved external symbol "int __cdecl yyparse(void)" (?yyparse@@YAHXZ) referenced in function _main
When I try to compile this, I get the error: main.obj : error LNK2019: unresolved external symbol "int __cdecl yyparse(void)" (?yyparse@@YAHXZ) referenced in function _main
我是flex/bison的新手.任何帮助,将不胜感激. 如果有用的话,这里是我的parser.y文件:
I am a newbie in flex/bison. Any help would be appreciated. If it helps here is my parser.y file:
%error-verbose /* instruct bison to generate verbose error messages*/
%{
#include "astgen.h"
#define YYDEBUG 1
/* Since the parser must return the AST, it must get a parameter where
* the AST can be stored. The type of the parameter will be void*. */
#define YYPARSE_PARAM astDest
extern int yylex();
%}
%union {
int val;
char op;
char* name;
struct AstElement* ast; /* this is the new member to store AST elements */
}
%token TOKEN_BEGIN TOKEN_END TOKEN_WHILE TOKEN_DO
%token<name> TOKEN_ID
%token<val> TOKEN_NUMBER
%token<op> TOKEN_OPERATOR
%type<ast> program block statements statement assignment expression whileStmt call
%start program
%{
/* Forward declarations */
void yyerror(const char* const message);
%}
%%
program: statement';' { (*(struct AstElement**)astDest) = $1; };
block: TOKEN_BEGIN statements TOKEN_END{ $$ = $2; };
statements: {$$=0;}
| statements statement ';' {$$=makeStatement($1, $2);}
| statements block';' {$$=makeStatement($1, $2);};
statement:
assignment {$$=$1;}
| whileStmt {$$=$1;}
| block {$$=$1;}
| call {$$=$1;}
assignment: TOKEN_ID '=' expression {$$=makeAssignment($1, $3);}
expression: TOKEN_ID {$$=makeExpByName($1);}
| TOKEN_NUMBER {$$=makeExpByNum($1);}
| expression TOKEN_OPERATOR expression {$$=makeExp($1, $3, $2);}
whileStmt: TOKEN_WHILE expression TOKEN_DO statement{$$=makeWhile($2, $4);};
call: TOKEN_ID '(' expression ')' {$$=makeCall($1, $3);};
%%
#include "astexec.h"
#include <stdlib.h>
void yyerror(const char* const message)
{
fprintf(stderr, "Parse error:%s\n", message);
exit(1);
}
我正在VS 2012环境中使用winflexbison生成解析器和词法分析器.构建过程非常简单.要做的就是在VS中将<appropriate>_custom_build.targets
添加到项目的构建自定义中,然后构建解决方案.可以在这里找到对文档的引用@ 用于Visual Studio的winflexbison .
EDIT 1: I am using winflexbison in VS 2012 environment to generate my parser and the lexer. The process for the build is rather simple. All that is required to be done is to add the <appropriate>_custom_build.targets
to build customizations for the project in VS and just build solution. A reference to the documentation can be found here @ winflexbison for Visual studio.
我还要指出,我遵循相同的方法来构建示例flex和bison文件,然后将其集成到项目中.这对我来说很好.
I would also like to point out that I followed the same method to build a sample flex and bison file and later integrated in a project. That worked fine for me.
我在做什么错了?
推荐答案
您的野牛输入中包含注释清楚但已过时的定义[注释1]:
Your bison input includes a well-commented but obsolete definition [note 1]:
/* Since the parser must return the AST, it must get a parameter where
* the AST can be stored. The type of the parameter will be void*. */
#define YYPARSE_PARAM astDest
如注释所示,这将导致yyparse
的原型为:
As the comment indicates, this will cause the prototype for yyparse
to be:
int yyparse(void* astDest);
但是,在您的main
函数中,您已经声明了
However, in your main
function, you've declared
extern int yyparse();
由于使用C ++进行编译,因此在main.cpp
中声明并由main
调用的yyparse
与在parser.tab.h
中声明并在parser.tab.cpp
中定义的yyparse
不同.因此,您会收到一个链接器错误.
Since you are compiling this with C++, the yyparse
declared in main.cpp
and invoked by main
is not the same function as the yyparse
declared in parser.tab.h
and defined in parser.tab.cpp
. Consequently, you get a linker error.
如果您将#include "parser.tab.h"
放入main.cpp
文件而不是手动声明yyparse
,则可能会看到更容易理解的错误消息,尽管我不能保证VS 2012产生的错误消息.
Had you put #include "parser.tab.h"
into your main.cpp
file instead of manually declaring yyparse
, you would probably have seen a more easily-understood error message, although I can't vouch for error messages produced by VS 2012.
注意:
-
YYPARSE_PARAM
自1.875年的野牛版以来就已不推荐使用,早在十多年前,它现在仅与yacc兼容的解析器一起使用.您应该使用%parse-param
声明,该声明可与所有由野牛产生的解析器一起使用,并且允许您指定实际的参数类型,而不必放弃类型安全性.有关详细信息,请参见《野牛手册》 .
YYPARSE_PARAM
has been deprecated since bison version 1.875, well more than a decade ago, and it currently only works with yacc-compatible parsers. You should use the%parse-param
declaration, which works with all bison-produced parsers, and which allows you to specify an actual parameter type rather than having to abandon type safety. See the bison manual for details.
这篇关于yyparse()的未解析外部符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!