error LNK2005

Hi.
I have this code and it doesn't work. I need help. Someone can explain why it doesn't work? Thank you.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
//Error.h

#ifndef CACL_ERROR_H
#define CACL_ERROR_H
namespace Error{
	struct Divide_0{};
	struct Syntax{
		const char* q;
		Syntax(const char* p){p=q;}
	};
}
#endif

//Lexer.h
 
#ifndef CALC_LEXER_H
#define CALC_LEXER_H
namespace Lexer{
	enum Tooken_Symbol{
		PLUS='+', MINUS='-', DIV='/', MUL='*', ASSIGN='=', LP1='(', RP=')', NUMBER 
	};
	Tooken_Symbol curr_symbol;
	Tooken_Symbol get_symbol();
}
#endif

//Parser.h

#ifndef CALC_PARSER_H
#define CALC_PARSER_H
namespace Parser{
	float primary();
	float term();
	float expr_S();
	float expr();
}
#endif

//Parser_impl.h

#ifndef CALC_PARSER_IMPL_H
#define CALC_PARSER_IMPL_H
#include"Parser.h"
#include"Lexer.h"
#include"Error.h"
namespace Parser{
	float primary();
	float term();
	float expr_S();
	float expr();
	using namespace Lexer;
	using Error::Divide_0;
	using Error::Syntax;
}
#endif 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//Lexer.cpp

#include<iostream>
#include"Lexer.h"
#include"Error.h"
using namespace std;
using namespace Lexer;
Tooken_Symbol get_symbol(){
	char ch;
	cin>>ch;
	switch(ch){
	case '0': case '1': case '2': case '3': case '4':
	case '5': case '6': case '7': case '8': case '9':
		cin.putback(ch);
		return curr_symbol=NUMBER;
	case PLUS:
	case MINUS:
	case MUL:
	case DIV:
	case ASSIGN:
	case LP1:
	case RP:
		return curr_symbol=Tooken_Symbol(ch);
	default:
		throw Error::Syntax("can't get symbol");
	}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//Parser.cpp

#include"Parser_impl.h"
#include"Parser.h"
#include<iostream>
using namespace std;
float Parser::primary(){
	float result;
	switch(curr_symbol){
	case NUMBER:
		cin>>result;
		break;
	case LP1:
		result=Parser::expr_S();
		break;
	}
	return result;
}
float Parser::term(){
	float result;
	get_symbol();
	switch(curr_symbol){
	case NUMBER:
	case LP1:
		result=Parser::primary();
		break;
	default:
		throw Error::Syntax("1.first primary isn't a number");
		break;
	}
	for(;;){
		get_symbol();
		if((curr_symbol==PLUS)||(curr_symbol==MINUS)||(curr_symbol==ASSIGN)||(curr_symbol==RP)) break;
		switch(curr_symbol){
		case MUL:
			get_symbol();
			switch(curr_symbol){
			case NUMBER:
			case LP1:
				result*=Parser::primary();
				break;
			case RP:
				break;
			default: 
				throw Error::Syntax("2.fail number");
			}
			break;
		case DIV:
			get_symbol();
			switch(curr_symbol){
			case NUMBER:
			case LP1:
				if(float d=Parser::primary()) result/=d; else throw Error::Divide_0();
				break;
			default:
				throw Error::Syntax("3.fail number");
			}
			break;
		case RP:
			break;
		default:
			throw Error::Syntax("4.fail number");
		}	
	}
	return result;
}
float Parser::expr(){
	float result=Parser::term();
	for(;;){
		if(curr_symbol==ASSIGN) break;
		if(curr_symbol==PLUS) result+=term();
		if(curr_symbol==MINUS) result-=term();
	}
	return result;
}
float Parser::expr_S(){
	float result=Parser::term();
	for(;;){
		if(curr_symbol==RP) break;
		if(curr_symbol==PLUS) result+=term();
		if(curr_symbol==MINUS) result-=term();
	}
	return result;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//main.cpp

#include<iostream>
#include<Windows.h>
#include<sstream>
#include"Parser.h"
#include"Error.h"
using namespace std;
int main(int argc, char* argv[])
{
	istream *input;
	switch(argc){
	case 1:
		input=&cin;
		break;
	case 2:
		input=new istringstream(argv[1]);
		break;
	default:
		Error::Syntax("can't detected error :D");
	}
	while(*input){
		try{
			cout<<Parser::expr()<<endl;
		}
		catch(Error::Divide_0) {
			cerr<<"Divide by zero"<<endl;
		}
		catch(Error::Syntax e){
			cerr<<"Syntax error: "<<e.q<<endl;
		}
	}
	system("pause");
	return 0;
}


It is based on the book "The C++ Programming Language".
Thank you.
I'm sorry. Its problem are: (I use Visual Studio)
1>Parser.obj : error LNK2005: "enum Lexer::Tooken_Symbol Lexer::curr_symbol" (?curr_symbol@Lexer@@3W4Tooken_Symbol@1@A) already defined in Lexer.obj
1>Parser.obj : error LNK2019: unresolved external symbol "enum Lexer::Tooken_Symbol __cdecl Lexer::get_symbol(void)" (?get_symbol@Lexer@@YA?AW4Tooken_Symbol@1@XZ) referenced in function "float __cdecl Parser::term(void)" (?term@Parser@@YAMXZ)
> "enum Lexer::Tooken_Symbol Lexer::curr_symbol" already defined in Lexer.obj
By including `Lexer.h', you'll have several sources that define the same global variable.
If you want that each unit has its own copy, declare the variable as static
If you want the variable to be shared, declare it as extern. You'll also need to define it in one (and just one) source file.

> unresolved external symbol "enum Lexer::Tooken_Symbol __cdecl Lexer::get_symbol(void)"
In `Lexer.cpp' you have defined ::get_symbol() but you need to define Lexer::get_symbol()
Yes. I understand what you say. But I can't solve it.
ne555 explained how to fix the problems.
Thank you. It work :happy:
Topic archived. No new replies allowed.