#include <stdio.h>
#include <iostream.h>
#include <vector>
#include <utility>
#include <string.h>
#include <fstream>
#include <algorithm>
#include <cstdlib>
using namespace std;
#define NUM 20 //临时字符串strtoken[NUM]中的空间
void Getchar();//从文件中读入字符
void getbc(); //忽略空格
void concat(); //连接字符
bool isletter();//判断是否为字母
bool isdigit(); //判断是否为数字
int reserve(); //判断是否为关键字,返回其在关键字数组中的位置
int insertid(char *strtoken);//插入到字符串数组中,返回其位置
int insertconst(char *strtoken);//插入到常数数组中,返回其位置
void procerror();//对其它字符的处理
void change(); //词法分析
void title(); //打印标题
void helpfile();//助记符的含义
static FILE *openfile(char *prompt,char *mode);//定义文件路径名与打开方式
FILE *fp,*fp1;//文件fp->打开文件(原文件);文件fp1->保存文件;
int m=0,n=0,h=0,point=0;
char ch;
char char_list[30][20],num_list[30][20];//字符串数组,常数数组
char program[100]; //保存输入的语句
char* keyword[]={"auto","break","case","char","const","continue",
"default","do","double","else","enum","extern",
"float", "for","goto","if","int","long","register",
"return", "short","signed","sizeof","static",
"struct","switch","typedef","union","unsigned",
"void","volatile","while","bool","catch","class",
"const_cast","delete","dynamic_cast","explicit",
"false","friend","inline","mutable","namespace",
"new","operator","private","protected","public",
"reinterpret_cast","static_cast","tempplate","this",
"throw","true","try","typeid","typename","using",
"virtual","wchar_t"};//关键字
char strtoken[NUM];//临时字符串
static FILE *openfile(char *prompt,char *mode)
{
char tmpFile[20]; //定义字符串数组保存输入的文件名
FILE *reval=NULL;
while(1)
{printf("%s:\n",prompt);
gets(tmpFile);
reval=fopen(tmpFile,mode);
if(reval!=NULL) break;
printf("error file%s",tmpFile);
exit(1);
}
return reval;
/*if(!(fp=fopen("d://a.txt","r")))
{printf("error");
exit(1);
}
ch=getc(fp);*/
}
void main()
{
cout<<"请输入分析文件的文件路径(source)!"<<endl;
fp=openfile("source","r");
ch=getc(fp);
cout<<"请输入要保存的文件路径(intention)!"<<endl;
fp1=openfile("intention","w");
title();
helpfile();
while(ch!=EOF)
{change();
}
fclose(fp);
fclose(fp1);
}
void Getchar()
{
ch=getc(fp);
}
void getbc()
{
ch=getc(fp);
if(ch==' ')
Getchar();
}
void concat()
{
strtoken[h]=ch;
h++;
}
bool isletter()
{
if ((ch<='z' && ch>='a')||(ch>='A' && ch<='Z'))
return 1;
else
return 0;
}
bool isdigit()
{
if (ch<='9' && ch>='0')
return 1;
else
return 0;
}
int reserve()
{
for (int i=0;i<61;i++)
if(strcmp(strtoken,keyword[i])==0)
return i;
return 0;
}
int insertid(char *strtoken)
{
strcpy(char_list[m],strtoken);
m++; //m记录插入的id数
return (m-1);
}
int insertconst(char *strtoken)
{
strcpy(num_list[n],strtoken);
n++; //n记录插入的const数
return (n-1);
}
void procerror()
{
cout<<ch<<" 无法识别符号!"<<endl;
fprintf(fp1,"%c",ch);
fprintf(fp1," 无法识别符号!\n");
Getchar();
}
void change() // 判定一个单词的判定程序
{
int code=1,value;
if(isletter() || ch=='_') //判定字符串是否是标识符
{
while (isletter() || isdigit() || ch=='_')
{
concat();
Getchar();
}
code=reserve(); //查询保留字表,检查当前标识符是否是保留字
if (code==0) //不是关键字
{
value=insertid(strtoken);
for(int i=0;i<NUM;i++)
{cout<<strtoken[i];fprintf(fp1,"%c",strtoken[i]);}//文件格式化输入到保存文件中(下同)
cout<<"$ID: "<<value<<endl;//返回$ID和其在标识符表中的编号
fprintf(fp1,"$ID:%d\n",value);
}
else //是关键字
{
for (int i=0;i<NUM;i++)
{cout<<strtoken[i];fprintf(fp1,"%c",strtoken[i]);}//文件格式化输入到保存文件中
cout<<"$ONLY: "<<code<<endl; //返回保留字在保留字表中的编号
fprintf(fp1,"$ONLY:%d\n",code);
}
}
else if (isdigit()) //判断是否为常数
{
while (isdigit())
{
concat();
Getchar();
}
if(!isletter() && ch!='_')
{
if(ch=='.') //是否为小数
{
concat();
Getchar();
while (isdigit())
{
concat();
Getchar();
}
}
value=insertconst(strtoken);
for (int i=0;i<NUM;i++)
{ cout<<strtoken[i]; fprintf(fp1,"%c",strtoken[i]);}
cout<<"$CONST: "<<value<<endl;//返回其在常数表中的编号
fprintf(fp1,"$CONST:%d\n",value);
}
else if(isletter() || ch=='_') //判断是否为非法标识符
{
while (isletter() || isdigit() || ch=='_')
{
concat();
Getchar();
}
for(int i=0;i<NUM;i++)
cout<<strtoken[i];
cout<<"非法标识符! "<<endl;
fprintf(fp1,"%d\n",strtoken[i]);
fprintf(fp1,"非法标识符");
}
}
else if (ch=='=')
{
Getchar();
if (ch=='=') //赋值号
{
cout<<"=="<<" $VALUE:--"<<endl;
fprintf(fp1,"== $VALUE:--\n");
Getchar();
}
else //等号
cout<<"="<<" $ASSIGN:--"<<endl;
fprintf(fp1,"= $ASSIGN:--\n");
}
else if (ch=='!')
{
Getchar();
if (ch=='=') //不等号
{
cout<<"!="<<" $NOTEQUAL:--"<<endl;
fprintf(fp1,"!= $NOTEQUAL:--\n");
Getchar();
}
else //感叹号
cout<<"!"<<" $OHDEAR:--"<<endl;
fprintf(fp1,"! $OHDEAR:--\n");
}
else if (ch=='+')
{
Getchar();
if (ch=='+') //加一操作
{
cout<<"++"<<" $POWERADD:--"<<endl;
fprintf(fp1,"++ $POWERADD:--\n");
Getchar();
}
else //加号
cout<<"+"<<" $ADD:--"<<endl;
fprintf(fp1,"+ $ADD:--\n");
}
else if (ch=='-')
{
Getchar();
if (ch=='-') //减一操作
{
cout<<"--"<<" $POWERSUB:--"<<endl;
fprintf(fp1,"-- $POWERSUB:--\n");
Getchar();
}
else //减号
cout<<"-"<<" $SUB:--"<<endl;
fprintf(fp1,"- $SUB:--\n");
}
else if (ch=='*')
{
Getchar();
if (ch=='*') //平方
{
cout<<"**"<<" $POWER:--"<<endl;
fprintf(fp1,"** $POWER:--\n");
Getchar();
}
else //乘号
cout<<"*"<<" $STAR:--"<<endl;
fprintf(fp1,"* $STAR:--\n");
}
else if (ch=='/') //判断是否为除号、注释
{
Getchar();
if(ch=='/') //“//”注释,跳过该注释
while(ch!='\n' && ch!=EOF)
Getchar();
else if(ch=='*') //“/* */”注释,跳过该注释
{
Getchar();
loop: while(ch!='*' && ch!=EOF)
Getchar();
if(ch==EOF) //若无“*/”与“/*”匹配,则跳过“/*”后面的所有语句
return;
else
{
Getchar();
if(ch!='/')
goto loop;
else
Getchar();
}
}
else //除号
cout<<"/"<<" $HALF:--"<<endl;
fprintf(fp1,"/ $HALF:--\n");
}
else if(ch=='<')
{
Getchar();
if(ch=='=') //小于或等于号
{
cout<<"<="<<" $NOTLARGER:--"<<endl;
fprintf(fp1,"<= $NOTLARGER:--\n");
Getchar();
}
else //输出号
if(ch=='<')
{
cout<<"<<"<<" $OUTSIGN:--"<<endl;
fprintf(fp1,"<< $OUTSIGN:--\n");
Getchar();
}
else //小于号
cout<<'<'<<" $LESSTHAN:--"<<endl;
fprintf(fp1,"< $LESSTHAN:--\n");
}
else if(ch=='>')
{
Getchar();
if(ch=='=') //大于或等于号
{
cout<<">="<<" $NOTLESS:--"<<endl;
fprintf(fp1,">= $NOTLLESS:--\n");
Getchar();
}
else
if(ch=='>') //输入号
{
cout<<">>"<<" $INSIGN:--"<<endl;
fprintf(fp1,">> $INSIGN:--\n");
Getchar();
}
else //大于号
cou