⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bianyi2005.cpp

📁 c编译器词法分析程序源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:








#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <typeinfo.h> 
#include <iostream.h> 
#include <iomanip.h> 

#define MAX_LENTH_KEY_TOKEN 12 
#define KEY_No 34 
#define MAX_LINE_LENGTH 81 

/****************数据类型定义**********************/ 

typedef struct Token 
{ 
char *Biao_zhi_fu; //标志符的长度不应超过20 
int Number; 
struct Token *next; 
}Token; //将词法分析的结果用链表表式出来 

typedef struct hash_table // 
{ 
char KEY[MAX_LENTH_KEY_TOKEN+1]; //[MAX_LENTH_KEY_TOKEN+1] 
int identifer; 
struct hash_table *next; 
}hash_table; //采取这种带链表到哈希表进行存贮关键字,对语言中新的关键字的扩充很有利 像C++,Java,Dephi中的关键字就非常多 

typedef struct change_token //对所有的变量用链表进行存贮,防止变量没定义就被使用 
{ 
char *Bianliang; 
int which_kind; // int? char? unsigned? long? 
struct change_token *next; 
}change_token; //规定存贮变量名称。常量 

typedef struct mistake 
{ 
char *ch; //指明哪个词,短语 出了错 
int mistake_kind; //错误原因 存贮错误原因代码 节省空间 
int hang_hao; 
struct mistake *next; 
}mistake; //报错功能 

/*****************************关键字及其标志符归纳列表******************************************/ 

char *KEY[KEY_No]={{"auto"},{"break"},{"char"},{"case"},{"continue"},{"const"},{"double"},{"default"}, 
{"define"},{"do"},{"else"},{"extern"},{"enum"},{"for"},{"float"},{"goto"},{"int"},{"if"}, 
{"include"},{"long"},{"return"},{"register"},{"struct"},{"static"},{"short"},{"switch"}, 
{"sizeof"},{"signed"},{"typedef"},{"union"},{"unsigned"},{"void"},{"volatile"},{"while"}}; 
//关键字表,将用做哈希查找 total 34 from 0 to 33 

char Limit[] = ";,.=<>!&|\"+-*/%'{}()[]:#\\"; //tatal 25 from 34 to 64 

#define BIANLIANG 65 //变量一律用65做代码号 
#define FUNCTION 66 //变量一律用66做代码号 
#define NUMBER 67 //数字一律用67做代码号 
#define ZIFUCHUAN 68 
#define SHUCHULIU 69 


//用户自己定义的标志符(包括常量和变量) 60 
//函数(包括系统函数和用户自己定义的函数) 61 


/**************************为了程序操作方便,定义如下全局变量**************************************/ 

Token *Token_begin = new Token; // build the first link for the output 
Token *t_point = Token_begin; 

hash_table *key_table = new hash_table[26]; //key_word table 
hash_table *k_point = key_table; 

//hash_table *hash = new hash_table[26]; 

change_token *begin = new change_token; 
change_token *c_point = begin; 

mistake *mistake_begin = new mistake; 
mistake *m_point = mistake_begin; 

int hang_shu; //文件中的定位 
int flag = 0; //eg; char ch; <correct> ; ch <incorrect>;char read[201]; //一次读入一行源代码,这一行允许的最大长度是200 
char input[50]; //对读入的一行源代码分段进行处理 
char before[15]; 
char before_before[15]; 
char read[81]; 
int i; // 
int back; //是否为.h的头文件 
int mistake_number; 
char Filename[40]; 
int if_return; 
int count; 

/************************************************************************************************/ 

void Create_hash_table() 
{ 
for(int i=0;i<KEY_No;i++) 
{ 
if(key_table[KEY[i][0]-'a'].identifer == -1) 
{ 
strcpy(key_table[KEY[i][0]-'a'].KEY ,KEY[i]); //point should apply the room 
key_table[KEY[i][0]-'a'].identifer = i; 
key_table[KEY[i][0]-'a'].next = NULL; 

} 
else 
{ 
hash_table *s = new hash_table; 
//s->KEY = new ch[strlen(KEY[i]+1)]; 
strcpy(s->KEY,KEY[i]); 
s->identifer = i; 
s->next = NULL; 

s->next = key_table[KEY[i][0]-'a'].next; 
key_table[KEY[i][0]-'a'].next = s; 
} 
} 

} 



void add_to_the_link(int dai_hao) //maybe & it doesn't need 
{ //correct 
Token *s = new Token; 
s->Biao_zhi_fu = new char[strlen(input)+1]; 
strcpy(s->Biao_zhi_fu ,input); 
s->Number = dai_hao; 
s->next = NULL; 

t_point->next = s; 
t_point = s; 
} 

void add_to_the_change_token() 
{ 
change_token *p = new change_token; 
p->Bianliang = new char[strlen(input)+1]; 
strcpy(p->Bianliang ,input); 
p->which_kind = flag; 
p->next = NULL; 

c_point->next = p; 
c_point = p; 

/*s->next = begin->next; 
begin->next = s;*/ 
} 


void add_to_the_wrong_line(int mistake_kind_number) //& 
{ 
mistake *q = new mistake; 
q->ch = new char[strlen(input)+1]; 
strcpy(q->ch ,input); 
q->mistake_kind = mistake_kind_number; 
q->hang_hao = hang_shu; 
q->next = NULL; 

mistake_number++; 

m_point->next = q; 
m_point = q; 
} 

bool if_defined() // 
{ 
change_token *r = begin->next ; //*********warning : r并没有申请内存空间 
while(r) 
if(!stricmp(r->Bianliang,input) ) 
return true; 
else 
r = r->next ; 

return false; 
} 

bool if_head_file(int cur) 
{ 
cur++; 
if(read[cur]!='\n'&&read[cur]==' ') 
cur++; 
/*if(read[cur]=='<<endl') 
{ 
if_return = 1; 
return false; 
}*/ 
if(read[cur]=='h') 
return true; 
else 
return false; 
} 

int see_the_after(int cur) 
{ 
while(read[cur]!='\n') 
if(read[cur]==' ') 
cur++; 
else 
break; 

if(read[cur]=='('||read[cur]==')') 
return 1; 
else if(read[cur]=='.'&&if_head_file(cur)) 
{ 
strcat(input,".h"); 
return 2; 
} 
else 
return 0; 

} 

bool see_before_before(int cur) 
{ 
if(cur==-1) 
return false; 
while(cur>=0&&read[cur]==' ') //向前回朔识别 
cur--; 

int m = 0; 
if(cur>=0) 
{ 
while(cur>=0&&read[cur]>='a'&&read[cur]<='z') 
before_before[m++] = read[cur--]; 
if(cur>=0) 
{ 
before_before[m] = 0; 
strrev(before_before); 

if(!stricmp(before_before,"unsigned")) 
return true; 
else 
return false; 
} 
} 
return false; 

} 

bool if_biangliang(int cur) 
{ 
cur-= strlen(input); 
cur--; 


while(cur>=0&&read[cur]==' ') //向前回朔识别 
cur--; 

flag = 0; 
int m = 0; 

while(cur>=0&&read[cur]>='a'&&read[cur]<='z') 
before[m++] = read[cur--]; 

before[m] = 0; 
strrev(before); 

if(!stricmp("int",before)) 
{ 
if(see_before_before(cur)) //是否为unsigned int 
flag = 2; 
else 
flag = 1; 
return true; 
} 
else if(!stricmp("long",before)) 
{ 
if(see_before_before(cur)) 
flag = 4; 
else 
flag = 3; 
return true; 
} 
else if(!stricmp("float",before)||!stricmp("double",before)||!stricmp("char",before)|| 
!stricmp("const",before)||!stricmp("struct",before)||!stricmp("enum",before)||!stricmp("union",before)) 
{ 
flag = 5; 
return true; 
} 
else 
{ 
return false; 
} 


} 

void if_key_word(int cur) 
{ 
if(input[0]>='a'&&input[0]<='z') 
{ 
hash_table *q = &key_table[input[i]-'a']; 

if(q->identifer != -1) 
{ 
while(q) 
if(!stricmp(q->KEY,input)) 
{ 
add_to_the_link(q->identifer); 
return; 
} 
else 
q = q->next ; 
} 
} 

int function_back = see_the_after(cur); 
if(function_back>0) 
{ 
add_to_the_link(FUNCTION); // 
if(function_back==2) 
back = 1; 
} 
else 
{ 
if(if_defined()) 
{ 
add_to_the_link(BIANLIANG); 
} 
else if(if_biangliang(cur)) 
{ 
add_to_the_link(BIANLIANG); 
add_to_the_change_token(); 
flag = 0; 
} 
else 
add_to_the_wrong_line(1); //变量没有定义 

} 
} 

/*void look_before(int cur) 
{ 
cur--; 
//char ch[15]; 
while(read[cur]==' ') 
cur--; 
for(int m=0;read[m]!=' ';m++) 
before[m] = read[m]; 
before[m] = 0; 

strrev(before); 

}*/ 

bool find_the_change_token_link(const char *p,int &which_kind) // 
{ 
change_token *t = begin->next ; 
while(t) 
{ 
if(!stricmp(t->Bianliang,p)) 
{ 
which_kind = t->which_kind ; 
return true; 
} 
else 
t = t->next ; 
} 

if(!t) 
return false; 


return false; 

} 


void seek_before(int cur,int &mis_kind) 
{ 
cur--; 
cur-=strlen(input); 
while(1) 
{ 
if(read[cur]>='0'&&read[cur]<='9'||read[cur]>='a'&&read[cur]<='z' 
||read[cur]>='A'&&read[cur]<='Z'||read[cur]=='_') 
break; 
else 
cur--; 
} 

int j = 0; 
char p[40]; //建议变量最长不超过40 

while(1) 
{ 
if(cur<0||read[cur]==','||read[cur]==';'||read[cur]=='('||read[cur]=='{'||read[cur]==' ') 
{ 
p[j] = 0; 
break; 
} 
else 
p[j++] = read[cur--]; 

} 

strrev(p); 

if(find_the_change_token_link(p,mis_kind)); 

else 
{ 
mis_kind = 1; //int 
} 

} 

bool if_overflow(int &mis_kind,int cur,int &mistake) 
{ 
int max_lenth_allow = 0; 
char wh[10]; 

seek_before(cur,mis_kind); 

switch(mis_kind) 
{ 
case 1: //int 
max_lenth_allow = 5; 
if(input[0]=='-') 
strcpy(wh,"-32768"); 
else 
strcpy(wh,"32767"); 
break; 
case 2: //unsigned int 
max_lenth_allow = 5; 
if(input[0]=='-') 
{ 
//add_to_the_wrong_line(); 
mis_kind = 0; // 5表示在unsigned中定义了负数 
mistake = 5; 
return false; 

} 
else 
strcpy(wh,"65535"); 
break; 
case 3: //long 
max_lenth_allow = 10; 
if(input[0]=='-') 
strcpy(wh,"-2147483648"); 
else 
strcpy(wh,"2147483648"); 
break; 
case 4: //unsigned long 
max_lenth_allow = 10; 
if(input[0]=='-') 
{ 
mis_kind = 0; 
mistake = 5; 
return false; 
} 
else 
strcpy(wh,"4294967295"); 
break; 
default: return true; 
} 


if(mis_kind) 
{ 
int len = strlen(input); 
if(input[0]=='-') 
{ 
if(len<max_lenth_allow+1) 
return true; 
else if(len==max_lenth_allow+1) 
{ 
if(stricmp(input,wh)<=0) 
return true; 
else 
{ 
mistake = 6; 
return false; 
} 
} 
else 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -