📄 main.h
字号:
#include <stdlib.h>
#include <fstream.h>
#include <string.h>
#include <malloc.h>
#include <stdio.h>
#include <iostream.h>
#define WORD 0x0
#define NUMERIC 0x2
#define COMMENTS 0x3
#define INTERIEAVE 0x4
#define CONSTANT 0x1
#define ILLEGAL 0x5
char codebuf[100][100]; //源代码总缓冲区
char CodeingList[60][100];//编码表存储
int SumLine;
typedef struct errornote //错误记录结构
{
int line; //错误所在行
int row; //错误所在列
int num; //错误总行数
int kind; //错误类型 :1 注释为闭合2 小数点错误3
}ENote;
//堆栈操作
typedef struct character
{
char word;
character *next;
}ch; //堆栈结点结构
typedef struct dualitynode //二远组结构
{
int num; //种别码
int value; //单词自身值
dualitynode *next;
}DUALITY;
typedef struct name
{
int Pos; //起始位置
int len; //长度
}NAME;
enum type{No,integer,real,character};
enum kind{no,constant};
//标识符都没有类型,种属和值
//字符常量类型为字符,种属为常数,没有值
//数字常量类型为整,实,种属为常数,有值,无名字
typedef struct symboltable //符号表结构
{
NAME strname; //名字
type typesign; //类型
kind kindsign; //种属
char *value; //数值,以字符形式形式存储
}ST;
////////////////////////////////////////////////
//符号表类
class table
{
ST *st; //符号表指针
char *str; //符号串0 预留
int item; //符号表总项数,0项预留
int len; //符号串长度
public:
table()
{
item=0;
len=0;
st=(ST *)malloc(sizeof(ST));
st[0].value=NULL;
str=NULL;
}
~table()
{
/*for(int i=0;i<=item;i++)
{
free(st[i].value);
}*/
free(st);
free(str);
}
int exame(char *content,int flag);
int findstr(char *sub,int pos);
bool writefile();
void display();
};
/////////////////////////////
class stack //堆栈类
{
ch *top; //栈顶指针
ch *base;
public:
stack();
~stack();
void push(char);
bool Pop(char &);
char * &getcontent();
void print();
};
////////////////////////////
class duality //2元组类
{
DUALITY *head; //全局变量,链表头
DUALITY *tail; //全局变量,链表尾
public:
duality()
{head=NULL;
tail=NULL;}
/*~duality()
{DUALITY *temp1,*temp2;
temp1=temp2=head;
while(temp1->next!=NULL)
{temp2=temp1->next;
free(temp1);
temp1=temp2;
}
free(temp1);
}*/
void fillduality(int n,int num);
bool writedualityfile();//将链表写入文件
void displayduality();
void displayduality(ofstream OutFile);
};
void readfile(char *filename,char bufname[][100]);//读源代码文件
char *Mygetline(int line); //读入一行字符
char getword(char *p,int &n); //读入一个字符
int judge(char substr[]); //查询编码表
int Translate(char temp); //字符转换
bool checkreal(char *ch);//判定是否为实数
void Getstackcontent(char tm[],stack &s); //获得堆栈的全部内容
void printerror();
//////////////////////////////////////////////
//函数实现
void readfile(char *filename,char bufname[][100])
{
char temp;
int line=0,ArrayPos=0,i=0;
ifstream InFile;
InFile.open(filename,ios::in);
line=0;
while(InFile.get(temp))
{
if(temp=='\n')
{
bufname[line][ArrayPos]='\0';
line++;
ArrayPos=0;
}
else
{
bufname[line][ArrayPos]=temp;
ArrayPos++;
}
}
SumLine=line+1;
InFile.close();
}
int table::findstr(char *sub,int pos)
{
int i=0,j=pos-1;
int slen=strlen(sub);
if(str==NULL)
{return 0;}
while(i<slen&&j<len)
{
if(sub[i]==str[j])
{i++;j++;}
else
{i=0;j=j-i+1;}
}
if(i==slen)
{return j-slen+1;}
else
{return 0;}
}
int table::exame(char *content,int flag)
{
int length;
int m;
int pos=1;
ST *temp;
char *p;
length=strlen(content);
if(flag==WORD||flag==CONSTANT) //如果是标识符后者字符常数
{
while(m=findstr(content,pos))//找到在字符串表中的位置,没找到返回0
{
for(int i=1;i<=item;i++)
{
//WORD值为0,CONSTANT值为1,恰好和typesign值对应
//找到字符值相同的,再判断类型是否想同
if((st[i].strname.Pos==m)&&((int)st[i].kindsign==flag)&&(st[i].strname.len==length))
{
{return i;}
}//找到入口并返回
}
pos=m+length;
}
//没找到则插入新项
temp=(ST *)realloc(st,(item+2)*sizeof(ST));//给符号表增加空间
st=temp;
st[item+1].strname.Pos=len+1; //填写name项
st[item+1].strname.len=length;
p=(char *)realloc(str,len+length+1);
str=p;
for(int i=0;i<=length;i++) //将新串添加到字符串中
{str[len+i]=content[i];}
//strcat(str,content); //把新串添加到符号串中
len=len+length;
item++; //符号表项加1
if(flag==CONSTANT) //根据标识符或者字符常量填写不同内容
{st[item].kindsign=constant;
st[item].typesign=character;
}
else
{st[item].kindsign=no;
st[item].typesign=No;
} //填写其他项
st[item].value=NULL;
return item; //返回符号表入口
}
else //如果是数字常量
{
if(st!=NULL)
{
for(int i=1;i<=item;i++)
{
if(st[i].value!=NULL)
{if(!strcmp(st[i].value,content))//顺序查找值相同的项
{return i;}//返回入口
}
}
}
//如果没有找到,也添加一项
st=(ST *)realloc(st,(item+2)*sizeof(ST));//给符号表增加空间
st[item+1].strname.Pos=0; //填写name项
st[item+1].strname.len=0;
item++; //符号表项加1
st[item].kindsign=constant; //填写其他项
st[item].value=(char *)malloc(length);
strcpy(st[item].value,content);
st[item].typesign=integer;
for(int i=0;i<length;i++) //判断是否为实数
{
if(content[i]=='.')
{st[item].typesign=real;
break;
}
}
return item;
}
}
bool table::writefile()
{
ofstream OutFile;
OutFile.open("table.txt",ios::out);
if(!OutFile)
{
cerr<<"can't open this file"<<endl;
return false;
}
OutFile.width(10);
OutFile<<"name";
OutFile.width(10);
OutFile<<"type";
OutFile.width(10);
OutFile<<"kind";
OutFile.width(10);
OutFile<<"value";
OutFile.width(10);
OutFile<<"addr"<<'\n';
for(int i=1;i<=item;i++)
{
if(st[i].strname.Pos==0)
{
OutFile.width(10);
OutFile<<" ";
}
else
{
OutFile.width(5);
OutFile<<st[i].strname.Pos;
OutFile.width(5);
OutFile<<st[i].strname.len;
}
if(st[i].kindsign==constant)
{
OutFile.width(10);
OutFile<<"constant";
}
else
{
OutFile.width(10);
OutFile<<" ";
}
if(st[i].typesign==no)
{
OutFile.width(10);
OutFile<<" ";
}
else
{
if(st[i].typesign==real)
{OutFile.width(10);
OutFile<<"real";}
if(st[i].typesign==integer)
{OutFile.width(10);
OutFile<<"integer";}
if(st[i].typesign==character)
{OutFile.width(10);
OutFile<<"character";}
}
if(st[i].value==NULL)
{
OutFile.width(10);
OutFile<<" "<<endl;
}
else
{
OutFile.width(10);
OutFile<<st[i].value<<endl;
}
OutFile<<'\n';
}
OutFile<<str<<'\n';
}
void table::display()
{
cout.width(10);
cout<<"name";
cout.width(10);
cout<<"type";
cout.width(10);
cout<<"kind";
cout.width(10);
cout<<"value";
cout.width(10);
cout<<"addr"<<endl;
for(int i=1;i<=item;i++)
{
if(st[i].strname.Pos==0)
{
cout.width(10);
cout<<" ";
}
else
{
cout.width(5);
cout<<st[i].strname.Pos;
cout.width(5);
cout<<st[i].strname.len;
}
if(st[i].kindsign==constant)
{
cout.width(10);
cout<<"constant";
}
else
{
cout.width(10);
cout<<" ";
}
if(st[i].typesign==no)
{
cout.width(10);
cout<<" ";
}
else
{
if(st[i].typesign==real)
{cout.width(10);
cout<<"real";}
if(st[i].typesign==integer)
{cout.width(10);
cout<<"integer";}
if(st[i].typesign==character)
{cout.width(10);
cout<<"character";}
}
if(st[i].value==NULL)
{
cout.width(10);
cout<<" "<<endl;
}
else
{
cout.width(10);
cout<<st[i].value<<endl;
}
cout<<'\n';
}
printf("%s",str);
}
char *Mygetline(int line) //从缓冲区读一行字符
{
char *temp;
temp=codebuf[line-1];
return temp;
}
char getword(char *p,int &n) //从一行字符读一个字符
{
char temp;
temp=p[n-1];
n++;
return temp;
}
int judge(char substr[]) //查询编码表,筛选出关键字,也用于搜索分界符
{
int Pos=0,len;
//readfile("date.ls"); //可在主函数中预先读出
len=strlen(substr);
while(Pos<60)
{
if(strcmp(substr,CodeingList[Pos])==0)
{break;}
Pos++;
}
if(Pos>59)
{return 0;} //如果没找到返回0
return Pos+1; //返回种别码
}
inline stack::stack()
{
top=new ch;
top->next=NULL;
}
inline stack::~stack()
{
ch *temp1,*temp2;
temp1=top;
while(temp1->next!=NULL)
{
temp2=temp1->next;
delete temp1;
temp1=temp2;
}
}
void stack::print() //打印
{
ch *temp;
if(top->next==NULL)
{cout<<"stack is empty!"<<endl;
return;
}
temp=top;
cout<<temp->word<<endl; //从栈头打印到栈尾
temp=temp->next;
while(temp->next!=NULL)
{
cout<<temp->word<<endl;
temp=temp->next;
}
}
void stack::push(char w) //字符压栈
{
ch *p;
p=new ch;
p->word=w;
p->next=top;
top=p;
}
bool stack::Pop(char &p) //字符出栈
{
ch *temp;
if(top->next==NULL)
{
return false;
}
p=top->word;
temp=top;
top=temp->next;
delete temp;
return true;
}
int Translate(char temp) //字符转换函数
{
int n;
n=(int)temp;
if(n<91&&n>64||n>96&&n<123)
{
return WORD; //字符
}
if(n>47&&n<58)
{
return NUMERIC;//数字常量
}
if(n==47)
{
return COMMENTS;//注解符 /
}
if(n>39&&n<48||n>57&&n<63||n>90&&n<94||n==124)
{
return INTERIEAVE;//分界符
}
if(n==39)
{
return CONSTANT; //字符常量标志'
}
if(n!=' '&&n!='\0')
{
return ILLEGAL; //非法字符
}
return -1;
}
bool checkreal(char *ch)//判定是否为实数
{
for(int i=0;i<strlen(ch);i++)
{if(ch[i]=='.')
return true;
}
return false;
}
void printerror(ENote *eNote)
{
int i;
ofstream OutFile;
if(!OutFile)
{
cerr<<"can't open this file"<<'\n';
return;
}
OutFile.open("errorfile.txt",ios::out);
for(i=0;i<eNote[0].num;i++)
{
switch(eNote[i].kind)
{
case 1:
printf("error %d:line %d row %d 注释未闭合\n",
i+1,eNote[i].line,eNote[i].row);
OutFile<<"error "<<i+1<<":line "<<eNote[i].line
<<" row "<<eNote[i].line<<" 注释未闭合"<<'\n';
break;
case 2:
printf("error %d:line %d row %d 小数点重复\n",
i+1,eNote[i].line,eNote[i].row);
OutFile<<"error "<<i+1<<":line "<<eNote[i].line
<<" row "<<eNote[i].line<<"小数点重复"<<'\n';
break;
case 3:
printf("error %d:line %d row %d 非法标识符\n",
i+1,eNote[i].line,eNote[i].row);
OutFile<<"error "<<i+1<<":line "<<eNote[i].line
<<" row "<<eNote[i].line<<"非法标识符"<<'\n';
break;
case 4:
printf("error %d:line %d row %d 引号不封闭\n",
i+1,eNote[i].line,eNote[i].row);
OutFile<<"error "<<i+1<<":line "<<eNote[i].line
<<" row "<<eNote[i].line<<"引号不封闭"<<'\n';
break;
case 5:
printf("error %d:line %d row %d 非法字符\n",
i+1,eNote[i].line,eNote[i].row);
OutFile<<"error "<<i+1<<":line "<<eNote[i].line
<<" row "<<eNote[i].line<<"非法字符"<<'\n';
break;
}
}
}
void duality::fillduality(int n,int num)//n:种别码,num 符号表入口号,如果为0就不存在
{
DUALITY *temp;
temp=(DUALITY *)malloc(sizeof(DUALITY));
temp->num=n;
temp->value=num;//如果是关键字或界符值为0,输出时输出'_';
//符号表从1开始
if(head==NULL) //向链表添加一项
{
tail=head=temp;
temp->next=NULL;
return;
}
tail->next=temp;
tail=temp;
tail->next=NULL;
return;
}
void duality::displayduality()
{
DUALITY *temp=head;
if(temp==NULL)
{return;}
while(temp->next!=NULL)
{cout<<temp->num<<" ";
if(!temp->value)
{cout<<'_'<<endl;}
else
{cout<<temp->value<<endl;}
temp=temp->next;
}
cout<<temp->num<<" ";
if(!temp->value)
cout<<'_'<<endl;
else
cout<<temp->value<<endl;
}
void duality::displayduality(ofstream OutFile)
{
DUALITY *temp=head;
if(head==NULL)
{return;}
while(temp->next!=NULL)
{OutFile<<temp->num<<" ";
if(!temp->value)
{OutFile<<'_'<<'\n';}
else
{OutFile<<temp->value<<'\n';}
temp=temp->next;
}
OutFile<<temp->num<<" ";
if(!temp->value)
OutFile<<'_'<<'\n';
else
OutFile<<temp->value<<'\n';
}
bool duality::writedualityfile()//将链表写入文件
{
ofstream OutFile;
OutFile.open("tokens.txt",ios::out);
if(!OutFile)
{
cerr<<"can't open this file"<<endl;
return false;
}
displayduality(OutFile);
OutFile.close();
return true;
}
void Getstackcontent(char tm[],stack &s)
{
int n=0,i=0;
char temp;
while(s.Pop(temp)) //将字符全部出栈存入tm中
{
for(int n=i;n>0;n--)
{tm[n]=tm[n-1];}
tm[0]=temp;
i++;
}
tm[i]='\0';
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -