yyprse()的未解析外部符号
unresolved external symbol for yyparse()
我的main.cpp看起来像这样:
#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:error LNK2019: unresolved external symbol "int __cdecl yyparse(void)" (?yyparse@@YAHXZ) referenced in function _main
我是flex/bison的新手。如有任何帮助,我们将不胜感激。如果有帮助的话,这里是我的解析器.y文件:
%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:%sn", message);
exit(1);
}
EDIT1:我在VS 2012环境中使用winflexbison来生成我的解析器和lexer。构建过程相当简单。所需要做的就是将<appropriate>_custom_build.targets
添加到VS中项目的构建自定义项中,然后只构建解决方案。该文档的参考资料可以在@winflexbison for Visual studio中找到。
我还想指出,我采用了相同的方法构建了一个示例flex和bison文件,后来集成到了一个项目中。这对我来说很好。
我在这里做错了什么?
您的野牛输入包括一个注释良好但过时的定义[注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
的原型为:
int yyparse(void* astDest);
然而,在main
函数中,您已经声明了
extern int yyparse();
由于是用C++编译的,所以main.cpp
中声明并由main
调用的yyparse
与parser.tab.h
中声明并在parser.tab.cpp
中定义的yyparse
不是同一个函数。因此,您会得到一个链接器错误。
如果您将#include "parser.tab.h"
放入main.cpp
文件,而不是手动声明yyparse
,您可能会看到一条更容易理解的错误消息,尽管我不能保证VS 2012产生的错误消息。
注:
YYPARSE_PARAM
自十多年前的bison 1.875版本以来就一直被弃用,目前它只能与yacc兼容的解析器一起使用。您应该使用%parse-param
声明,它适用于所有bison生成的解析器,并且允许您指定实际的参数类型,而不必放弃类型安全性。有关详细信息,请参阅野牛手册
您需要使用Bison从语法文件生成一个C文件。然后,您需要编译该C文件(默认情况下将命名为y.tab.c
(,并将其与包含main
定义的C文件链接。
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- 未解析的外部符号_MsiLocateComponentW@12.
- 在C++中使用 gRPC 时未解析的外部符号
- LibPrivoxy: 未解析的外部符号 __declspec(dllimport) int __stdcall Sta
- 尝试从 XamlApplication 编译 C++/WinRT 空白应用程序时,我收到未解析的外部符号 winrt_make_*
- 我收到错误LNK2001:未解析的外部符号(C++代码)
- 可视抽象类 c++(错误 LNK 2001:未解析的外部符号)
- 如何摆脱C++中未解析的外部符号"private: static char"错误?
- 当 lib 已添加到其他依赖项时,如何在 VS 中调试未解析的外部符号错误
- 仅在少数方法(静态或共享库)中解析的外部符号
- 未解析的外部符号"__declspec(dllimport)与 Spdlog c++ 库
- 函数 _main (OPENGL C++) 中引用的未解析的外部符号 ________
- 错误LNK2019未解析的外部符号"public: __thiscall SLinkList<char>::SLinkList<char>(void)"
- 使用静态 constexpr 成员的未解析外部符号
- 引入参数化构造函数后显示 LNK 2019 未解析外部符号的代码错误
- Dlib LNK2001未解析的外部符号USER_ERROR__consistent_build_configurati
- 矛盾的未解决的外部符号+未使用的库与VS2017和FFMPEG 4
- 链接器错误:切换到unicode生成给出:未解析的外部符号WinMain
- 类模板上一个特定函数的未解析外部符号
- LNK2001:未解析的外部符号public:static类std::vector