📄 cifafenxi.cpp
字号:
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<fstream>
#include<string>
#include<stack>
#include<cmath>
#include<vector>
using namespace std;
#define Length 61
#define N 100
#define Size 100
/*************************定义结构********/
struct token//单词表结构
{
int label;/*单词序号*/
char name[30];/*单词本身*/
int code;//单词的机内码
int addr;//标识符或常数在符号表中的入口地址
};
//符号表文件结构
struct Symble
{ int number;
int type;
char name[30];
};
vector<string> st;//向量用于回填
//关键字结构
struct KeyWord
{
char name[30];
int code;
};
//产生式结构
struct ChanShengShi
{
string left;//左部
string right;//右部
int len;
};
//action表结构,栈
struct Action
{
char cha;//栈内字符
int state;//状态
};
struct Data
{
int zt;
string word;
};
stack<token>s1;//token栈
stack<token>s2;//token栈的逆序
stack<string>YuyiStack;
/****************************变量定义*******/
char ch;//字符
int fu_count;//记录三地址的个数
int var_count;//输入字符数
int error_count;//错误个数
int addr_count;
int label_count;//单词序号数
int code_count;//单词机内码数
int LineOfPro;//记录行数
char filename[30];//文件名
int q;
FILE *KeyFin;//关键字文件输入
FILE *SourceFin;//文件输入源
FILE *TokenFout;//分析文件输出
FILE *SymbleFout;
FILE *SdzFout;
KeyWord key[Length];//关键字
token CurrentToken;//
Symble CurrentSymble;
Symble SymbleList[N];
ChanShengShi css[18];//产生式数组
Action action[45][18];//action表
int GoTo[45][8];
string l[N];//字符串数组用于存放三地址的字符串
/**************************函数定义*********/
void ttttt();
void ttt();
void tt();
void ScannerInit();//扫描初始化
void IsAlpha();//判断是不是字符
void IsNumber();//判断是不是数字
void IsAnotation();//判断是不是注释符
void IsChar();//判断是不是字符
void IsOther();//判断是否为其他字符
void OutPut();//输出
void Error(int a);//出错处理
void Scanner();//扫描
int WordHave();
void Analys();//语法分析
void AnalysInit();//语法分析初始化
void InitState();
void InitFuhao();
void pushState(int x);
void pushFuhao(string x);
void popState();
void popFuhao();
string getTop();
int Fuzhi(int i);
int BianGoto1(string p);
int strcmp(char*s,char*t)//比较函数
{
for(;*s==*t;s++,t++)
if(*s==0)return 0;
return 1;
}
void huitian(vector<string> & a,int t1,int t2);
int too1;
int kbb;
int to2,to3,to4,to5;
void print(vector<string> a);//打印输出
/***************主程序*******************/
int main()
{
int i=0,j=0;
code_count=0;
too1=0;
to2=0;
to3=0;
to4=0;
to5=0;
fu_count=0;
LineOfPro=0;
addr_count=1;
var_count=0;
label_count=1;
YuyiStack.push("@");
for(i=0;i<N;i++)
{ l[i]="\0";
SymbleList[i].number=0;
SymbleList[i].type=0;
for(j=0;j<30;j++)
SymbleList[i].name[j]='\0';
}
Scanner();
Analys();
if(to4!=0)
{
huitian(st,to2,to4);
huitian(st,to3,kbb);
huitian(st,to4,0);
huitian(st,to5,kbb);
}
else
{
huitian(st,to2,0);
huitian(st,to3,kbb);
}
print(st);
// huitian(st,1,3);
// vector<string>::iterator it=st.begin();
// cout<<*it<<endl;
// cout<<to2<<to3<<to4<<to5<<endl;
return 0;
}
/*************词法分析*******************************************/
void Scanner()
{
int i=0;
error_count=0;
ScannerInit();
printf(" **********************************\n");
printf(" 编译器\n");
printf(" **********************************\n");
printf("输入源文件名:");
for(;;)
{
scanf("%c",&filename[i]);
if(filename[i]==10)
break;
i++;
}
filename[i]='\0';
if((SourceFin=fopen(filename,"rt"))==NULL)
{
printf("无法打开文件 %s.\n",filename);
exit(1);
}
if((TokenFout=fopen("token.txt","wt+"))==NULL)
{
printf("无法打开文件 token.txt.\n");
exit(1);
}
if((SymbleFout=fopen("symble.txt","wt+"))==NULL)
{
printf("无法打开文件 symble.txt\n");
exit(1);
}
printf("词法分析:\n");
ch=fgetc(SourceFin);//读取第一个字符
while(ch!=EOF)
{
for(i=0;i<30;i++)
CurrentToken.name[i]='\0';
if((ch>47)&&(ch<58))
{
IsNumber();//数字
}
else
{
if(((ch>64)&&(ch<90))||((ch>96)&&(ch<123))||ch=='_')
{
IsAlpha();//字母
}
else
{
if(ch=='/')
{
IsAnotation();//注释符
}
else if(ch=='\'')
{
IsChar();//字符串
}
else
IsOther();//其他符号
}
}
}
fclose(SourceFin);//关闭文件
fclose(TokenFout);
fclose(SymbleFout);
printf("词法分析完毕.\n");
printf("\n");
}
/****************初始化**********************/
void ScannerInit()
{
int i=1;
int k=0;
if((KeyFin=fopen("jineima.txt","rt"))==NULL)
{
printf("Can not open jineima.txt.\n");
exit(1);
}
for(i=0;i<60;i++)
for(k=0;k<30;k++)
key[i].name[k]='\0';
for(i=0;i<60;i++)
{
fscanf(KeyFin,"%s%d",key[i].name,&key[i].code);
}
fclose(KeyFin);
}
/*********************数字处理**************************/
void IsNumber()
{
int k=0;
int flag=0;//标识符
char ch1;
while(((ch>47)&&(ch<58)))//字符为数字
{
CurrentToken.name[k++]=ch;//记录当前字符
ch=fgetc(SourceFin);
if(ch=='.')//字符为小数点
{
flag=1;/*为实数标记*/
break;
}
}
//记录单词编码为整数的编码
CurrentToken.code=28;//整常数
CurrentToken.addr=addr_count++;
CurrentToken.label=label_count++;
if(flag)//实数
{
ch1=fgetc(SourceFin);
{
if((ch1>47)&&(ch1<58))
{
CurrentToken.name[k++]=ch;
ch=ch1;
while((ch>47)&&(ch<58))
{
CurrentToken.name[k++]=ch;
ch=fgetc(SourceFin);
}
CurrentToken.code=29;//实常数
}
else Error(2);
if(ch=='.')//过滤掉余下的数字
{
Error(2);
ch=fgetc(SourceFin);
while((ch>47)&&(ch<58))
{
ch=fgetc(SourceFin);
}
}
}
}
if(((ch>64)&&(ch<90))||((ch>96)&&(ch<123)))//当前字符为字母舍去尾部
{
Error(2);
while(((ch>64)&&(ch<90))||((ch>96)&&(ch<123)))
{
ch=fgetc(SourceFin);
while((ch>47)&&(ch<58))
ch=fgetc(SourceFin);
}
}
OutPut();
}
/************字母处理*******************************/
void IsAlpha()//识别保留字和标识符
{
int i,h;
h=0;
i=0;
while(((ch>64)&&(ch<90))||((ch>96)&&(ch<123))||ch=='_')
{
CurrentToken.name[i++]=ch;//记录当前字符
ch=fgetc(SourceFin);
}
for(i=0;i<Length;i++)
{
h=strcmp(CurrentToken.name,key[i].name);//判断所记字符是否为保留字
if(!h)
break;
}
if(!h)
{
CurrentToken.code=key[i].code;
CurrentToken.addr=-1;
}
else
{
CurrentToken.code=27;
CurrentToken.addr=addr_count++;
}
CurrentToken.label=label_count++;
OutPut();
}
/************字符处理*********************************/
void IsChar()
{
int i=0;
for(;;)
{
ch=fgetc(SourceFin);
CurrentToken.code=30;
if(ch!='\'')
CurrentToken.name[i++]=ch;
else
break;
}
CurrentToken.addr=addr_count++;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
}
/**********************其他情况*******************************/
void IsOther()
{
char ch1;
int i;
for(i=0;i<30;i++)
CurrentToken.name[i]='\0';
switch(ch)
{
case '(': CurrentToken.name[0]='(';
CurrentToken.code=32;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case ')': CurrentToken.name[0]=')';
CurrentToken.code=33;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case '*': CurrentToken.name[0]='*';
CurrentToken.code=34;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case '+': CurrentToken.name[0]='+';
CurrentToken.code=35;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case '-': CurrentToken.name[0]='-';
CurrentToken.code=32;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case ',': CurrentToken.name[0]=',';
CurrentToken.code=37;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case '.': CurrentToken.name[0]='.';
CurrentToken.code=38;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case ':': ch1=ch;
ch=fgetc(SourceFin);
if(ch!='=')
{
CurrentToken.name[0]=':';
CurrentToken.code=40;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
}
else
{
CurrentToken.name[0]=':';
CurrentToken.name[1]='=';
CurrentToken.code=41;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
}
break;
case ';': CurrentToken.name[0]=';';
CurrentToken.code=42;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case '<': ch1=fgetc(SourceFin);
if(ch1=='=')
{
CurrentToken.name[0]='<';
CurrentToken.name[1]='=';
CurrentToken.code=44;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch1=fgetc(SourceFin);
}
else
{
if(ch1=='>')
{
CurrentToken.name[0]='<';
CurrentToken.name[1]='>';
CurrentToken.code=45;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch1=fgetc(SourceFin);
}
else
{
CurrentToken.name[0]='<';
CurrentToken.code=43;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
}
}
ch=ch1;
break;
case '=': CurrentToken.name[0]='=';
CurrentToken.code=46;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case'>':ch1=fgetc(SourceFin);
if(ch1=='=')
{
CurrentToken.name[0]='>';
CurrentToken.name[1]='=';
CurrentToken.code=48;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch1=fgetc(SourceFin);
}
else
{
CurrentToken.name[0]='>';
CurrentToken.code=47;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
}
ch=ch1;
break;
case '{': CurrentToken.name[0]='{';
CurrentToken.code=49;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -