📄 bianyi2005.cpp
字号:
#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 + -