我正在尝试使用C++
,flex
和bison
创建一种简单语法的玩具语言。我有四个文件:types.hpp
,scanner.l
,parser.y
和Makefile
。当我正在尝试编译时,对于types.hpp
内的每个函数,ld表示已经定义了它。我想这个问题在include指令中。这是我在每个文件开头的内容(我省略了语法内容,因为我认为这不是原因;如果有需要,我会发布它):
// scanner.l
%{
#include "parser.hpp"
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <string>
using namespace std;
extern "C" {
int yylex(void);
} /* extern "C" */
char BUFFER[32768];
int POSITION;
%}
%option noyywrap
%x COMMENT
%x BYTESMODE
%x indent
%s normal
// parser.y
%{
#include <iostream>
using namespace std;
extern "C" {
int yylex(void);
int yyparse(void);
int yywrap() { return 1; }
} /* extern "C" */
void yyerror(const char *error) {
cerr << error << endl;
} /* error handler */
%}
/*============================================================================*/
/* Create Bison union and stack */
/*============================================================================*/
%code requires {
#include "types.hpp"
}
%union {
object_type* pointer;
type_type* type_buffer;
none_type* none_buffer;
bool_type* bool_buffer;
int_type* int_buffer;
float_type* float_buffer;
bytes_type* bytes_buffer;
} /* union */
// types.hpp
#include <iostream>
#include <typeinfo>
#include <sstream>
#include <string>
using namespace std;
//============================================================================//
// Declare classes
//============================================================================//
class object_type;
class none_type;
class type_type;
class bool_type;
class int_type;
class float_type;
class bytes_type;
type_type type_function(object_type* object);
bytes_type name_function(object_type* object);
bytes_type repr_function(object_type* object);
bool_type bool_function(object_type* object);
int_type int_function(object_type* object);
float_type float_function(object_type* object);
bytes_type bytes_function(object_type* object);
// Makefile
caesar: scanner.l parser.y types.hpp
clear && clear && clear
bison -d parser.y -o parser.cpp --graph
flex -o scanner.cpp scanner.l
g++ -Wall -g -o $@ parser.cpp scanner.cpp -lfl
哪里有错误?我想这很简单,但由于我是C ++的新手,我很难找到它。提前致谢!如果需要,我会发布整个代码。
以下是错误消息的示例。
/home/ghostmansd/lang/types.hpp:559: multiple definition of `repr_function(object_type*)'
/tmp/ccv2zJdS.o:/home/ghostmansd/lang/types.hpp:559: first defined here
答案 0 :(得分:1)
问题是您在头文件中有实现,例如
type_type::~type_type(void) { /* destructor */ }
这需要转到types.cpp,在types.hpp中你应该只有类定义(除非你内联那些东西,但那将是第二步)。这是因为如果types.hpp被包含多次,那么你还有两个实现,它们是链接器不喜欢的。
您也不应该在types.hpp中声明变量。
答案 1 :(得分:1)
您可以在头文件中定义常量:
const none_type NONE_TYPE;
const bool_type BOOL_TYPE;
const int_type INT_TYPE;
const float_type FLOAT_TYPE;
const bytes_type BYTES_TYPE;
这会导致链接过程中出现问题,因为相同的符号会多次出现。
避免这个问题的一种方法:
您应该只在标题中将这些声明为外部:
extern const none_type NONE_TYPE;
extern const bool_type BOOL_TYPE;
extern const int_type INT_TYPE;
extern const float_type FLOAT_TYPE;
extern const bytes_type BYTES_TYPE;
仅在一个cpp文件中定义:
const none_type NONE_TYPE;
const bool_type BOOL_TYPE;
const int_type INT_TYPE;
const float_type FLOAT_TYPE;
const bytes_type BYTES_TYPE;
同样的问题似乎也出现在标题的函数定义中。