我做的c-的词法分析器,可是出现了下面的问题,不知该怎么办了
你能帮帮我吗?我的源文件是 main.cpp
#include "globals.h"
#include "util.h"
#include "scan.h"
int main(int argc, char* argv[])
{
sourceFile=fopen("sourceFile.txt","r");
listOutFile=fopen("listOutFile.txt","w");
while( getToken()!=ENDFILE){
}
return 0;
}
scan.cpp
#include "globals.h"
#include "util.h"
#include "scan.h"
#define BUFLEN 256
static struct //保留字的结构
{
char* str;
TokenType tok;
}reservedWords[MAXRESERVED] //给保留字结构数组附值
={
{"if",IF},{"int",INT},{"else",ELSE},
{"return",RETURN},{"while",WHILE},{"void",VOID}};
typedef enum
{ START,INNUM,INID,DONE,
INAOE,INASSIGN,
INOOC,INCOMMENT,INOUTCOM,
INLOE,INLT,INLE,
INROE,INRT,INRE,
INNE
} StateType;
static char lineBuf[ BUFLEN ] ; //一行的缓冲字符
static int linepos=0; //在一行的具体位置
static int bufsize=0; //缓冲的大小
static TokenType reservedLookup(char * s) //保留字的查找
{
int i;
for(i=0;i<MAXRESERVED;i++)
{
if(!strcmp(s,reservedWords[i].str))
return reservedWords[i].tok ;
}
return ID;
}
static char getNextChar() //得到 下一个字符
{
//sourceFile=fopen("sourceFile.txt","r"); //找不到文件。
if(sourceFile==NULL)
{
printf("sourceFile null");
exit(0);
}
// listOutFile=fopen("listOutFile.txt","w"); //
if(listOutFile==NULL)
{
printf("listOutFile null");
exit(0);
}
EchoSource=1;
if(!(linepos<bufsize))
{
lineNo++;
if(fgets(lineBuf,BUFLEN-1,sourceFile)) //从sourceFile中读取内容
{
if(EchoSource)
fprintf(listOutFile,"%4d:%s",lineNo,lineBuf);
bufsize=strlen(lineBuf);
linepos=0;
return lineBuf[linepos++];
}
else
return EOF;
}
else
return lineBuf[linepos++];
}
static void ungetNextChar() //读字符的位置往回走一个
{
linepos--;
}
TokenType getToken()
{
int tokenStringIndex= 0 ;
TokenType currentToken ;
StateType state = START ;
int save ;
while(state!=DONE)
{
char c=getNextChar();
save=TRUE;
switch(state)
{
case START:
if(isdigit(c))
state=INNUM ;
else if(isalpha(c))
state=INID ;
else if(c==' '||(c=='/t'||(c=='/n')))
save =FALSE ;//false
else if(c=='<')
state=INLOE;
else if(c=='=')
state=INAOE;
else if(c=='>')
state=INROE;
else if(c=='/')
{
save=FALSE;
state=INOOC;
}
else
{
state=DONE;
switch(c)
{
case EOF:
save=FALSE;//false
currentToken=ENDFILE; break;
case '+':
currentToken=PLUS; break;
case '-':
currentToken=MINUS; break;
case '*':
currentToken=TIMES; break;
case '(':
currentToken=LPAREN; break;
case ')':
currentToken=RPAREN; break;
case '[':
currentToken=LBRACK; break;
case ']':
currentToken=RBRACK; break;
case '{':
currentToken=LBRACE; break;
case '}':
currentToken=RBRACE; break;
case ';':
currentToken=SEMI; break;
case ',':
currentToken=COMMA;break;
default:
currentToken=ERROR; break;
}
}
break;
case INID:
if (!isalpha(c))
{
ungetNextChar();
save=FALSE;
state=DONE;
currentToken=ID;
}
break;
case INNUM:
if (!isdigit(c))
{
ungetNextChar();
save=FALSE;
state=DONE;
currentToken=NUM;
}
break;
case INLOE:
if(c=='='){
save=FALSE;
state=DONE;
currentToken=LE;
}else{
ungetNextChar();
save=FALSE;
state=DONE;
currentToken=LT;
}
break;
case INOOC:
save=FALSE;
if(c == '*'){
state=INCOMMENT;
currentToken =LCOMMENT;
}
else
{
ungetNextChar();
save=FALSE;
currentToken=OVER;
state=DONE;
}
break ;
case INCOMMENT:
save=FALSE;
if(c=='*')
state =INOUTCOM;
break;
case INOUTCOM:
if(c=='/'){
save=FALSE;
currentToken=RCOMMENT;
state=START;
}
else{
save=FALSE;
state =INCOMMENT;
}
break;
case INAOE:
state=DONE;
if( c == '=')
currentToken=EQ;
else
{
ungetNextChar();
save=FALSE; //false
currentToken=ASSIGN;
}
break;
case DONE:
default:
fprintf(listOutFile,"scan bug:state=%d/n",state);
state=DONE;
currentToken=ERROR;
break;
} //switch 结束
if((save)&&(tokenStringIndex<=MAXTOKENLEN))
tokenString[tokenStringIndex++]=c;
if(state== DONE)
{
tokenString[tokenStringIndex]='/0';
if(currentToken==ID)
currentToken=reservedLookup(tokenString); //判断当前Token是否为保留字
}
} //while循环结束
if(!TraceScan)
{
fprintf(listOutFile,"/t%d: ",lineNo);
printToken(currentToken,tokenString);
}
return currentToken;
}
util.cpp
#include "globals.h"
#include "util.h"
void printToken(TokenType token,const char * tokenString) //按照具体的格式打印出token的内容
{
switch(token)
{
case IF:
case INT:
case ELSE:
case VOID:
case WHILE:
case RETURN:
fprintf(listOutFile,"reserved word:%s/n",tokenString);
break;
case ASSIGN:fprintf(listOutFile,"=/n");break;
case LT:fprintf(listOutFile,"</n");break;
case LE:fprintf(listOutFile,"<=/n");break;
case NE:fprintf(listOutFile,"!=/n");break;
case EQ:fprintf(listOutFile,"==/n");break;
case RT:fprintf(listOutFile,">/n");break;
case RE:fprintf(listOutFile,">=/n");break;
case LPAREN:fprintf(listOutFile,"(/n");break;
case RPAREN:fprintf(listOutFile,")/n");break;
case LBRACK:fprintf(listOutFile,"[/n");break;
case RBRACK:fprintf(listOutFile,"]/n");break;
case LBRACE:fprintf(listOutFile,"{/n");break;
case RBRACE:fprintf(listOutFile,"}/n");break;
case SEMI:fprintf(listOutFile,";/n");break;
case COMMA:fprintf(listOutFile,",/n");break;
case PLUS:fprintf(listOutFile,"+/n");break;
case MINUS:fprintf(listOutFile,"-/n");break;
case TIMES:fprintf(listOutFile,"*/n");break;
case OVER:fprintf(listOutFile,"//n");break;
case ENDFILE:fprintf(listOutFile,"EOF/n");break;
case NUM:fprintf(listOutFile,"NUM,value= %s/n",tokenString);break;
case ID:fprintf(listOutFile,"ID,name= %s/n",tokenString);break;
case ERROR :fprintf(listOutFile,"ERROR:%s/n",tokenString);break;
default:
fprintf(listOutFile,"UNKNOWN token:%d",token);
}
}
char * copyString(char *s)
{
int n;
char *t;
if(s==NULL)
return NULL;
n=strlen(s)+1;
t=(char*)malloc(n);
if(t==NULL)
fprintf(listOutFile,"out of memory error at line: %d/n",lineNo);
else
strcpy(t,s);
return t;
}
globals.h
#ifndef _GLOBALS_H_
#define _GLOBALS_H_
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#define MAXRESERVED 6
typedef enum{
ENDFILE,ERROR,
IF,ELSE,INT,RETURN,VOID,WHILE,
ID,NUM,
ASSIGN,EQ,NE,
PLUS,MINUS,TIMES,OVER, //加减乘除
LT,LE,RT,RE, //小于 小于等于 大于 大于等于
SEMI,COMMA,//分号,逗号
LPAREN,RPAREN,//左右小括号
LBRACK,RBRACK,//左右中括号
LBRACE,RBRACE,//左右大括号
LCOMMENT,RCOMMENT //左右注释
}TokenType;
FILE * sourceFile;//=fopen("sourceFile.txt","wr");
FILE * listOutFile;//=fopen("listOutFile.txt","wr");
FILE * codeFile;//=fopen("codeFile.txt","wr");
int EchoSource;
int TraceScan;
int TraceCode;
int Error;
int lineNo;
#endif
}
scan.h
#ifndef _SCAN_H_
#define _SCAN_H_
#define MAXTOKENLEN 40
char tokenString[MAXTOKENLEN+1];
TokenType getToken();
static char getNextChar();
#endif
util.h
#ifndef _UTIL_H_
#define _UTIL_H_
void printToken(TokenType,const char * );
char *copyString(char *);
#endif
到底怎么回事啊,都查了一晚上了,都没办法。。。。
compiling...
main.cpp
scan.cpp
util.cpp
Linking...
scan.obj : error LNK2005: "int EchoSource" (?EchoSource@@3HA) already defined in main.obj
scan.obj : error LNK2005: "int lineNo" (?lineNo@@3HA) already defined in main.obj
scan.obj : error LNK2005: "struct _iobuf * codeFile" (?codeFile@@3PAU_iobuf@@A) already defined in main.obj
scan.obj : error LNK2005: "char * tokenString" (?tokenString@@3PADA) already defined in main.obj
scan.obj : error LNK2005: "int TraceCode" (?TraceCode@@3HA) already defined in main.obj
scan.obj : error LNK2005: "struct _iobuf * listOutFile" (?listOutFile@@3PAU_iobuf@@A) already defined in main.obj
scan.obj : error LNK2005: "struct _iobuf * sourceFile" (?sourceFile@@3PAU_iobuf@@A) already defined in main.obj
scan.obj : error LNK2005: "int Error" (?Error@@3HA) already defined in main.obj
scan.obj : error LNK2005: "int TraceScan" (?TraceScan@@3HA) already defined in main.obj
util.obj : error LNK2005: "int EchoSource" (?EchoSource@@3HA) already defined in main.obj
util.obj : error LNK2005: "int lineNo" (?lineNo@@3HA) already defined in main.obj
util.obj : error LNK2005: "struct _iobuf * codeFile" (?codeFile@@3PAU_iobuf@@A) already defined in main.obj
util.obj : error LNK2005: "int TraceCode" (?TraceCode@@3HA) already defined in main.obj
util.obj : error LNK2005: "struct _iobuf * listOutFile" (?listOutFile@@3PAU_iobuf@@A) already defined in main.obj
util.obj : error LNK2005: "struct _iobuf * sourceFile" (?sourceFile@@3PAU_iobuf@@A) already defined in main.obj
util.obj : error LNK2005: "int Error" (?Error@@3HA) already defined in main.obj
util.obj : error LNK2005: "int TraceScan" (?TraceScan@@3HA) already defined in main.obj
Debug/C handmake.exe : fatal error LNK1169: one or more multiply defined symbols found
执行 link.exe 时出错.
Creating browse info file...
C handmake.exe - 1 error(s), 0 warning(s)
这个错误到底怎么回事啊~~~~qiu gao ren help~