📄 编译原理.cpp
字号:
/*
Name: Lexical Analysis
Copyright: GUN Copyleft
Author: Liuguo
Class No.:1925205
Date: 11/11/07 14:04
Description: An experiment under course by Louie
*/
#define MAX_ATTRIBUTE_SIZE 500
#define MAX_IDENTIFIER_STACK_SIZE 100
#define MAX_IDENTIFIER_LENGTH 32
//#define TEST
#define OUTPUT "output.txt"
#define EOR -1
#define OK 0
#define LASTCONSTANT 8
#define NONE "none"
#define CONFIG "config.ini"
#define ID_ENTIFIER "[identifier]"
#define CON_STANT "[constant]"
#define SYM_BOL "[symbol]"
#define KEY_WORD "[keyword]"
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
//the most useful struct
typedef struct Lnode{
char content[10];
struct Lnode *next;
}Lnode,*node;
//Definition Of Each Table Struct
typedef struct identifier{//Identifier Table struct
char ident[MAX_IDENTIFIER_LENGTH];//identifier name
node machine;
}identifier,*IDENTABLE;
typedef struct constant{//Constant Table struct
char cons[MAX_IDENTIFIER_LENGTH];
node machine;
}constant,*CONSTABLE;
typedef struct symbol{//Symbols table struct
char symbols[10];
node machine;
}symbol,*SYMBLE;
typedef struct keywd{//keyword table struct
char keyword[10];
node machine;
}keywd,*KEYBLE;
typedef struct idstack{//identifier stack struct
IDENTABLE element;
int *stacktop;
int *stackbottom;
int element_num;
}idstack,*IDENTACK;
//do configure file check
int config_check(char *FILE_NAME)
{
char del[32]="erase ";
int i=6;
ofstream pickfile(FILE_NAME,ios::app);
pickfile.close();
ifstream needfile(FILE_NAME);
if(needfile.get()==-1)
{
cout<<"ERROR,the file "<<FILE_NAME<<" is missing!"<<endl;
needfile.close();
getchar();
while(*FILE_NAME)
{
del[i++]=*FILE_NAME;
FILE_NAME++;
}
system(del);
return EOR;
}
needfile.close();
return OK;
}
void outinit()
{
ofstream outf(OUTPUT);
char p[50]="/*By 刘国栋,1925205 for 编译原理 实验*/";
int i=0;
char s;
while(p[i])
{
s=p[i++];
outf.put(s);
}
outf.put('\n');
outf.close();
}
//Table Initialization
int ident_init(IDENTABLE table)
{
char ch;
char str[20]={'\0'};
Lnode *p,*q;
int i=0;
ifstream myfile(CONFIG);
table->machine=new Lnode;
p=q=table->machine;
ifstream fileopen(CONFIG);
while(!fileopen.eof())//loacting the load position
{
for(;i>0;i--) str[i]='\0';//initlise cache
while(1)
{
fileopen.get(ch);
if(ch=='\n'||fileopen.eof())
break;
str[i++]=ch;
}
if(strcmp(str,ID_ENTIFIER)==0)
break;
}
//in position
for(;i>0;i--) str[i-1]='\0'; //need do it again
while(1)
{
fileopen.get(ch);
if(((ch!=' ')&&(ch!='\n'))&&!fileopen.eof())//字符不是空格或换行且没有到文件尾
str[i++]=ch;
if (str[0]!='\0'&&((ch==' ')||(ch=='\n')))
{
p->next=q; p=p->next;
strcpy(p->content,str);//此处赋值
q=new Lnode;
}
if(ch=='\n')
break;
if(ch==' ')
for(;i>0;i--)
str[i-1]='\0';
if(fileopen.eof())
{
fileopen.close();
return OK;
}
}
p->next=NULL;//分配后指针不为0
#ifdef TEST
p=table->machine;
while(p)
{
cout<<p->content;
p=p->next;
}
cout<<endl;
#endif
return OK;
}
int cons_init(CONSTABLE table)
{
char ch;
char str[20]={'\0'};
Lnode *p,*q;
int i=0;
table->machine=new Lnode;
p=q=table->machine;
ifstream fileopen(CONFIG);
while(!fileopen.eof())//loacting the load position
{
for(;i>0;i--) str[i]='\0';//initlise cache
while(1)
{
fileopen.get(ch);
if(ch=='\n'||fileopen.eof())
break;
str[i++]=ch;
}
if(strcmp(str,CON_STANT)==0)
break;
}
//in position
for(;i>0;i--) str[i-1]='\0'; //need do it again
while(1)
{
fileopen.get(ch);
if(((ch!=' ')&&(ch!='\n'))&&!fileopen.eof())//字符不是空格或换行且没有到文件尾
str[i++]=ch;
if (str[0]!='\0'&&((ch==' ')||(ch=='\n')))
{
p->next=q; p=p->next;
strcpy(p->content,str);//此处赋值
q=new Lnode;
}
if(ch=='\n')
break;
if(ch==' ')
for(;i>0;i--)
str[i-1]='\0';
if(fileopen.eof())
{
fileopen.close();
return OK;
}
}
p->next=NULL;//分配后指针不为0
#ifdef TEST
p=table->machine;
while(p)
{
cout<<p->content;
p=p->next;
}
cout<<endl;
#endif
return OK;
}
int sym_init(SYMBLE table)
{
char ch;
char str[20]={'\0'};
Lnode *p,*q,*front;
int i=0;
//start of position
ifstream fileopen(CONFIG);
while(!fileopen.eof())//loacting the load position
{
for(;i>0;i--) str[i]='\0';//initlise cache
while(1)
{
fileopen.get(ch);
if(ch=='\n'||fileopen.eof())
break;
str[i++]=ch;
}
if(strcmp(str,SYM_BOL)==0)
break;
}//end of position
for(int k=0;k<19;k++)
{
table->machine=new Lnode;
p=q=table->machine;
//in position
for(;i>0;i--) str[i-1]='\0'; //need do it again
while(1)
{
fileopen.get(ch);
if(((ch!=' ')&&(ch!='\n'))&&!fileopen.eof())//字符不是空格或换行且没有到文件尾
str[i++]=ch;
if (str[0]!='\0'&&((ch==' ')||(ch=='\n')))
{
p->next=q;front=p; p=p->next;
strcpy(p->content,str);//此处赋值
q=new Lnode;
}
if(ch=='\n')
break;
if(ch==' ')
for(;i>0;i--)
str[i-1]='\0';
if(fileopen.eof())
{
fileopen.close();
return OK;
}
}
strcpy(table->symbols,p->content);
delete(p);//分配后指针不为0
front->next=NULL;
#ifdef TEST
p=table->machine;
while(p)
{
cout<<p->content;
p=p->next;
}
cout<<table->symbols<<endl;
#endif
table++;
}
return OK;
}
int key_init(KEYBLE table)
{
char ch;
char str[20]={'\0'};
Lnode *p,*q,*front;
int i=0;
//start of position
ifstream fileopen(CONFIG);
while(!fileopen.eof())//loacting the load position
{
for(;i>0;i--) str[i]='\0';//initlise cache
while(1)
{
fileopen.get(ch);
if(ch=='\n'||fileopen.eof())
break;
str[i++]=ch;
}
if(strcmp(str,KEY_WORD)==0)
break;
}//end of position
for(int k=0;k<8;k++)
{
table->machine=new Lnode;
p=q=table->machine;
//in position
for(;i>0;i--) str[i-1]='\0'; //need do it again
while(1)
{
fileopen.get(ch);
if(((ch!=' ')&&(ch!='\n'))&&!fileopen.eof())//字符不是空格或换行且没有到文件尾
str[i++]=ch;
if (str[0]!='\0'&&((ch==' ')||(ch=='\n')))
{
p->next=q; front=p;p=p->next;
strcpy(p->content,str);//此处赋值
q=new Lnode;
}
if(ch=='\n')
break;
if(ch==' ')
for(;i>0;i--)
str[i-1]='\0';
if(fileopen.eof())
{
fileopen.close();
return OK;
}
}
strcpy(table->keyword,p->content);
delete(p);//分配后指针不为0
front->next=NULL;
#ifdef TEST
p=table->machine;
while(p)
{
cout<<p->content;
p=p->next;
}
cout<<table->keyword<<endl;
#endif
table++;
}
return OK;
}
//输出处理
void outp(char *content )
{
int i=0;
char s;
ofstream outf(OUTPUT,ios::app);
while(content[i])
{
s=content[i++];
#ifdef TEST
cout<<s;
#endif
outf.put(s);
}
}
//字符处理
int getch(IDENTABLE itable,CONSTABLE ctable,SYMBLE stable,KEYBLE ktable,char *FILE_NAME)
{
char ch;
char cp[2]={'\0'};
int j;
Lnode *p;
IDENTABLE it=itable;
CONSTABLE ct=ctable;
SYMBLE st=stable;
KEYBLE kt=ktable;
ofstream outfile(OUTPUT,ios::app);
int last_flag=0;
char ss[10]={'\0'};
int i=0;
int dArray=0;
//LASTSYMBOL
//LASTCONSTANT
//LASTCHARAC
//LASTSPACE
int wline=1;//
ifstream getfile(FILE_NAME);
getfile.get(ch);
while(1)//ready to load characters
{
//if(getfile.eof())
if(getfile.eof())
break;
if(last_flag==1)
{
while(1)
{
getfile.get(ch);
if(ch=='*')
{
getfile.get(ch);
if(ch=='/')
{ last_flag=0;
getfile.get(ch);
if (getfile.eof())
return OK;
break;
}
else if(ch=='\n')
wline++;
else if(getfile.eof ())
return OK;
else
continue;
}
continue;
}
}
if(ch==' '||ch=='\n'||ch==' ')
{
if(ch=='\n') wline++;
getfile.get(ch);
continue;
}
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
{
ss[i++]=ch;
while(1)
{
getfile.get(ch);
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||(ch>='0'&&ch<='9'))
{
ss[i++]=ch;
continue;
}
for(j=0,kt=ktable;j<8;j++,kt++)
if(strcmp(ss,kt->keyword)==0)
break;//if检查是否为关键字,压入属性表序列
if(j<8)
{
p=kt->machine;
while(p)
{
outp(p->content);
//cout<<p->content;
outp(" ");
//cout<<" ";
p=p->next;
}
outp(kt->keyword);
outp("\n");
//cout<<kt->keyword<<endl;
}
else
{
p=it->machine;
while(p)
{
outp(p->content);
//cout<<p->content;
outp(" ");
//cout<<" ";
p=p->next;
}
outp(ss);
outp("\n");
//cout<<ss<<endl;
//标识符属性字输出
}
//else不是,制造标识符表插入属性表序列,if(last_identifier=1)压入标识符栈,last_identifier=0;if(last_identifier=0)
//查找标识栈,存在pass,不存在ERROR;
for(;i>0;i--)
ss[i-1]='\0';
break;
}
continue;
}
else if(ch>='0'&&ch<='9')
{
ss[i++]=ch;
while(1)
{
if(getfile.eof())
{
cout<<"文件结尾符错误"<<endl;
return EOR;
}
getfile.get(ch);
if((ch>='0'&&ch<='9')||ch=='.')
{
ss[i++]=ch;
continue;
}
else if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
{
cout<<"非法的标识符位于"<<wline<<"行"<<endl;
cout<<"标识符首位不能为数字"<<endl;
return EOR;
}
else
{
p=ct->machine;
while(p)
{
outp(p->content);
//cout<<p->content;
outp(" ");
//cout<<" ";
p=p->next;
}
outp(ss);
outp("\n");
//cout<<ss<<endl;
//查造常量表,压入属性字序列
}
for(;i>0;i--)
ss[i-1]='\0';
break;
}
continue;
}
else
{
ss[i++]=ch;
for(j=0,st=stable;j<19;j++,st++)
if(strcmp(ss,st->symbols)==0)
break;
if(j>=19)
{
cout<<"非法字符!";
return EOR;
}
if(j==16)
dArray=1;
getfile.get(ch);
if (!((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))&&!(ch>='0'&&ch<='9')&&(ch!=' ')&&(ch!='\n')&&!getfile.eof())
{
ss[i++]=ch;
cp[0]=ch;
for(j=0,st=stable;j<19;j++,st++)
if(strcmp(cp,st->symbols)==0) break;
if(j>=19)
{ cout<<"非法字符!";return EOR; }
if(j==15&&dArray==1)
{
cout<<"该程序不允许二维数组的出现,但是偏偏居然在"<<wline<<"行出现了"<<endl;
return EOR;
}
else dArray=0;
if(strcmp(ss,"/*")==0)
{
last_flag=1;
for(;i>0;i--)
ss[i-1]='\0';
continue;
}
for(j=0,st=stable;j<19;j++,st++)
if(strcmp(ss,st->symbols)==0) break;
if(j<19)
{
p=st->machine;
while(p)
{
outp(p->content);
//cout<<p->content;
outp(" ");
//cout<<" ";
p=p->next;
}
outp(st->symbols);
outp("\n");
//cout<<st->symbols<<endl;
for(;i>0;i--)
ss[i-1]='\0';
}
else
{
cp[0]=ss[0];
for(j=0,st=stable;j<19;j++,st++)
if(strcmp(cp,st->symbols)==0) break;
if(j<19)
{
p=st->machine;
while(p)
{
outp(p->content);
//cout<<p->content;
outp(" ");
//cout<<" ";
p=p->next;
}
outp(st->symbols);
outp("\n");
//cout<<st->symbols<<endl;
for(;i>0;i--)
ss[i-1]='\0';
continue;
}
}
}//end of if
for(j=0,st=stable;j<19;j++,st++)
if(strcmp(ss,st->symbols)==0) break;
p=st->machine;
while(p)
{
outp(p->content);
outp(" ");
//cout<<p->content;
//cout<<" ";
p=p->next;
}
outp(st->symbols);
outp("\n");
//cout<<st->symbols<<endl;
for(;i>0;i--)
ss[i-1]='\0';
continue;
}//endof else
}//end of while
return OK;
}
int main(int argc,char **args)
{
char FILE_NAME[32];
//memory allocation for identifier stack
IDENTACK istack=new idstack[MAX_IDENTIFIER_STACK_SIZE];
identifier *ident_ble=new identifier;
constant *const_ble= new constant;
symbol *sym_ble=new symbol[19];
keywd *key_ble=new keywd[8];
if(config_check(CONFIG))
return 0;
//初始化输出文件
outinit();
//initialization entrance
if(!(!ident_init(ident_ble)&&!cons_init(const_ble)&&!sym_init(sym_ble)&&!key_init(key_ble)))
{
cout<<"Error,the founction initialization failed!"<<endl
<<"Press any key to exit...";
getchar();
return 0;
}
//参数传递判断
if(argc==1)
{
cout<<"FILE_NAME:";
cin>>FILE_NAME;
getchar();
}
else if(argc!=2)
{
cout<<"Error,agrument is missing!";
return 0;
}
else
strcpy(FILE_NAME,*(++args));
if(config_check(FILE_NAME))
return 0;
if(getch(ident_ble,const_ble,sym_ble,key_ble,FILE_NAME))
cout<<"Error";
system(OUTPUT);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -