📄 cifa.cpp
字号:
// cifa.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "ctype.h"
#include "iostream.h"
#include "stdlib.h"
#include "fstream.h"
#include "string.h"
#define MaxNum 200
#define KeyNum 13
#define LEN 10
bool bufnil=true;//缓冲区为空标志
bool Fileend=false;//文件结束标志
int frp=0;//缓冲区指针
char buf[MaxNum];//输入缓冲区
char token[LEN];//装配单词能用缓冲区
char keytable[KeyNum][10]={"program","var","procedure","begin","end","if", "then",
"else","while","do","call","integer","real"};//保留字表
int IDfrp=1;//当前标识符表指针
struct ID_tab
{
int Recode;
char Idname[LEN];
int Idaddr;
}ID[MaxNum]; //标识符表
char readch(ifstream infile);//1、读一个字符
void isIdenti(ifstream infile,ofstream outfile,char ch);//2、判断标识符
int lookup();//3、检查当前标识符是否为保留字,不是返回零
void isInt(ifstream infile,ofstream outfile,char ch);//4、判断正整数
void Anno(ifstream infile,ofstream outfile);//5、越过注释
void report_err(ofstream outfile);//6、错误处理
void scanner(ifstream infile,ofstream outfile);//7、判断
char readch(ifstream infile)
{
char ch;
//缓冲区不空
if(!bufnil)
{
ch=buf[frp];
frp++;
if(ch=='\0') bufnil=true;//为下一次读字符设标志
return ch;
}
//缓冲区空
infile.getline(buf,sizeof(buf));//从文件中读一行
if(infile.eof()) Fileend=true;
else{
bufnil=false;
frp=0; //指针还原
ch=buf[frp];
frp++;
if(ch=='\0') bufnil=true;
return ch;
}
return '\0';//若文件中为空返回回车
}
int lookup()
{
int i;
for(i=0;i<KeyNum;i++)
if(strcmp(token,keytable[i])==0) return i+3;
return 0;
}
void isIdenti(ifstream infile,ofstream outfile,char ch)
{
int i=1;
token[0]=ch;
ch=readch(infile);
while(isalnum(ch))
{
token[i]=ch;
i++;
ch=readch(infile);
}
token[i]='\0';//串结束
frp--;
if(i>=8)
{
report_err(outfile);
return;
}
if(!lookup())//不是保留字
{
for(i=1;i<IDfrp;i++)
if(strcmp(token,ID[i].Idname)==0)//已出现的标识符再记录
{
outfile<<"(1,"<<i<<")"<<token<<endl;//读出标识符表中的序列号
return;
}
outfile<<"(1,"<<IDfrp<<")"<<token<<endl;
ID[IDfrp].Recode=IDfrp; //未出现的表示符记录到标识符表中
strcpy(ID[IDfrp].Idname,token);
ID[IDfrp].Idaddr=0;
IDfrp++;
}
else outfile<<"("<<lookup()<<","<<"0)"<<keytable[lookup()-3]<<endl;//保留字二元式
}
void isInt(ifstream infile,ofstream outfile,char ch)
{
int i=1,value=-1;
token[0]=ch;
value=ch-'0';
ch=readch(infile);
while(isdigit(ch))
{
value=value*10+ch-'0';
token[i++]=ch;
ch=readch(infile);
}
while(isalnum(ch))//是否字母或数字
{
value=-1;
ch=readch(infile);
}
token[i]='\0';
frp--;
if(value==-1) report_err(outfile);
else outfile<<"(2,"<<value<<")"<<value<<endl;
}
void Anno(ifstream infile,ofstream outfile)
{
char ch;
while(!Fileend)
{
ch=readch(infile);//碰到下一个*
if(ch=='*')
{
ch=readch(infile);//如果下一个是/
if(ch=='/')
{
return;
}
}
}
outfile<<"wrong Annotations!"<<endl;
}
void report_err(ofstream outfile)
{
outfile<<"**error(1)**"<<endl;
}
void scanner(ifstream infile,ofstream outfile)
{
char ch;
ch=readch(infile);
if(ch==' ')//跳过空格
{
ch=readch(infile);
while(ch==' ')
ch=readch(infile);
frp--;
}
else if(isalpha(ch))//判断标识符
isIdenti(infile,outfile,ch);
else if(isdigit(ch))
isInt(infile,outfile,ch);//判断正整数
else
switch(ch)//判别其他有效字符
{
case '\0':break;
case '+': outfile<<"(16,0)+"<<endl; break;
case '-': outfile<<"(17,0)-"<<endl; break;
case '*': outfile<<"(18,0)*"<<endl; break;
case '~': outfile<<"(20,0)~"<<endl; break;
case '^': outfile<<"(21,0)^"<<endl; break;
case '=': outfile<<"(27,0)="<<endl; break;
case '.': outfile<<"(31,0)."<<endl; break;
case ',': outfile<<"(32,0),"<<endl; break;
case ';': outfile<<"(30,0);"<<endl; break;
case '(': outfile<<"(33,0)("<<endl; break;
case ')': outfile<<"(34,0))"<<endl; break;
case ':': ch=readch(infile);
if(ch=='=') outfile<<"(29,0):="<<endl;
else { frp--; outfile<<"(35,0):"<<endl; }
break;
case '<': ch=readch(infile);
if(ch=='=') outfile<<"(24,0)<="<<endl;
else if(ch=='>') outfile<<"(28,0)<>"<<endl;
else { frp--; outfile<<"(23,0)<"<<endl; }
break;
case '>': ch=readch(infile);
if(ch=='=') outfile<<"(26,0)>="<<endl;
else { frp--; outfile<<"(25,0)>"<<endl; }
break;
case '/': ch=readch(infile);
if(ch=='*') Anno(infile,outfile);
else if(ch=='\\') outfile<<"(28,0)/\\"<<endl;
else { frp--; outfile<<"(19,0)/"<<endl; }
break;
case '\\':ch=readch(infile);
if(ch=='/') outfile<<"(22,0)\\/"<<endl;
else { frp--; outfile<<"**error(1)**"<<endl; }
break;
default: report_err(outfile);
break;
}
}
int main(int argc, char* argv[])
{
ifstream infile("D:\\fin.txt");
ofstream outfile("D:\\fout.txt");
if(!infile)
{
cout<<"file_in cannot open.\n";
abort();
}
while(!Fileend)
scanner(infile,outfile);
outfile<<endl;
outfile<<"序列\t"<<"名字\t"<<"地址\t"<<endl;
for(int i=1;i<IDfrp;i++)
outfile<<ID[i].Recode<<"\t"<<ID[i].Idname<<"\t"<<ID[i].Idaddr<<endl;
infile.close();
outfile.close();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -