📄 1.cpp
字号:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define BUFFER_SIZE 1000 //表达式缓冲区大小
#define CHAR_NUMBER 5 //输入字符的种类
#define Wmaxlen 256 //标示符的最大长度
char Buffer[BUFFER_SIZE]; //表达式缓冲区,以'\0'表示结束
char scult[BUFFER_SIZE];
int ipBuffer = 0; //表达式缓冲区当前位置序号
int ipscult = 0;
int n=0;
struct Fbuffer
{
int num; //num=1,2,3,4,5,6 1:基本保留字;2:标识符;3:常数;4:运算符;5:分隔符;6:其它
char value[Wmaxlen];
char error[Wmaxlen];//错误
}Fbuffer1[BUFFER_SIZE];
int ipFBuffer=0;
char KEY[26][26]={{"auto"},{"case"},{"if"},{"char"},{"const"},{"continue"},
{"default"},{"double"},{"long"},{"register"},{"switch"},{"else"},{"int"},{"for"},
{"while"},{"do"},{"return"},{"break"},{"continue"},{"short"},{"signed"},{"sizeof"},
{"static"},{"struct"},{"volatile"},{"void"}};
//int KEY_NO=strlen(KEY);
char ch; //存放取得的一个字符
//函数声明:
bool Run(); //对存储在缓冲区的一行字符串(以'#'结束)进行运行
void system(); //全局初始化
void input();//从键盘读入程序,存于表达式缓冲区Buffer[]中
char GetChar(char Buffer[BUFFER_SIZE]); //从缓冲区取一个字符,返回该字符的同时将它存于全局变量ch中
void scanner(char Buffer[BUFFER_SIZE]);//扫描程序
int pt(char ch);
void output();
void manalyse(char Buffer[BUFFER_SIZE]);//词法分析程序
void main()
{
system();
}
void system()
{
printf("============================================================================\n\n");
printf("程序功能:从输入的源程序中,先对程序进行扫描,并进行词法分析和语法分析。\n");
printf(" 1-- 输入程序和打开源程序\n");
printf(" 2-- 程序扫描\n");
printf(" 3-- 词法分析\n");
printf(" 4-- 语法分析\n");
printf(" 5-- 退出\n");
printf("============================================================================\n\n");
int sys;
bool exit=false,s1=false,s2=false,s3=false;
while(true)
{
printf("\n请输入数字1-5来选择功能: ");
scanf("%d",&sys);
if ( !(sys>=1 && sys<=5))
{
printf("你输入的数不正确:");
continue;
}
switch (sys)
{
case 1:
{
input();
s1=true;
break;
}
case 2:
{
if (!s1)
{
printf("您还没有输入源程序!!");
break;
}
else
{
scanner(Buffer);
s2=true;
break;
}
}
case 3:
{
if (!s2)
{
printf("建议你先扫描源程序!!");
break;
}
else
{
manalyse(Buffer);
break;
}
}
case 5: exit=true;break;
}
if (exit) break;
}
}
void input()
{
for (int i=0;i<=strlen(Buffer);i++)
Buffer[i]='\0';
ipFBuffer=0;
printf("请输入以\"@\"号结束的程序:\n");
ipBuffer = 0; //初始化缓冲区指针
while ((Buffer[ipBuffer]=getchar() )!='@')
{
ipBuffer++;
}
}
void output()
{
printf("\n------------------------源程序词法分析如下---------------------\n");
printf("%5s%16s%10s\n","类型值","数据类型","数据值");
for (int i=0;i<ipFBuffer;i++)
{
//printf("%5d ",i);
printf("%5d",Fbuffer1[i].num);
switch(Fbuffer1[i].num)
{
case 1 : printf(" 关键字 ");break;
case 2 : printf(" 标识符 ");break;
case 3 : printf(" 常数 ");break;
case 4 : printf(" 运算符 ");break;
case 5 : printf(" 分隔符 ");break;
case 6 : printf(" 其它 ");
}
for (int j=0;j<=strlen(Fbuffer1[i].value);j++)
printf("%c",Fbuffer1[i].value[j]);
printf("\n");
}
}
char GetChar(char Buffer[BUFFER_SIZE])
{
if((ch = Buffer[ipBuffer]) != '@')
ipBuffer ++;
return ch;
}
void scanner(char Buffer[BUFFER_SIZE]) //扫描程序,对它进行判断
{
for (int j=0;j<=strlen(scult);j++)
scult[j]='\0';
printf("\n扫描源程序开始!!\n");
ipBuffer=0;
int flat;
while (Buffer[ipBuffer]!='@') //扫描注释, 去掉没用程序
{
if (Buffer[ipBuffer]=='/' && Buffer[ipBuffer+1]=='/')
{
while (Buffer[ipBuffer]!='\n')
{
Buffer[ipBuffer]=32;
ipBuffer++;
}
}
if (Buffer[ipBuffer]=='/' && Buffer[ipBuffer+1]=='*')
{
while (!((Buffer[ipBuffer]='*') && (Buffer[ipBuffer+1]=='/')))
{
Buffer[ipBuffer]=32;
ipBuffer++;
}
Buffer[ipBuffer]=32;
Buffer[ipBuffer+1]=32;
}
ipBuffer++;
}
ipBuffer=0;
ch=GetChar(Buffer);
flat=pt(ch);
if (flat==5 || flat==0) //扫描没用的字符
printf("");
else
{
printf("%c",ch);
scult[ipscult++]=ch;
}
while(ch!='@') //将不同类型的这符用#号分开
{
ch=GetChar(Buffer);
if (ch=='@')
break;
if (pt(ch)==5 || pt(ch)==0)
printf("");
else if (flat!=pt(ch) || (flat==3)) //pt(ch)!=1 && flat==pt(ch)
{
printf("%c%c",'#',ch);
scult[ipscult++]='#';
scult[ipscult++]=ch;
}
else if (flat==pt(ch) && flat==2)
{
printf("%c",ch);
scult[ipscult++]=ch;
}
else
{
printf("%c",ch);
scult[ipscult++]=ch;
}
flat=pt(ch);
}
scult[ipscult]='#';
printf("\n扫描完成!!\n");
}
int pt(char ch)
{
if (ch>='a'&& ch<='z'|| ch>='A'&& ch<='Z'||ch>='0' && ch<='9'||ch==95)
return 1;
else if(ch==32)
return 0;
else if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='%'||ch=='>'||ch=='<'||ch=='='||ch=='!'||ch=='&'||ch=='~'||ch=='^')
return 2; //操作符
else if(ch==','||ch==';'||ch=='{'||ch=='}'||ch=='('||ch==')'||ch=='"'||ch=='['||ch==']')
return 3; //分隔符
else if (ch=='?'||ch==':')
return 4; //条件运算符
else return 5;//没有用的字符
}
void manalyse(char Buffer[BUFFER_SIZE])//从缓冲区中取一个单词
{
//printf("%d",ipscult);
//int scult=ipscult;
ipscult=0;
int k;//表示取出的字符放在单词数组的指针
ipFBuffer=0;
ipBuffer=0;
Fbuffer1[ipFBuffer].num=1; //预先定义的取出的单词的类型
char Word[Wmaxlen];
//scanner(Buffer);// 扫描程序去掉不能显示的字符
ipBuffer=0; //使数组指针回到开始。
char ch=GetChar(scult); //对扫描后的程序一个个字符取出。
//int p=1; //测试用的
while(ch!='\0')
{
bool flag=false;//用来表示取出的单词是否为关键词,如果是则flag的值为true,否则为false
//printf("第%d次\n",p++);//测试用的
if (ch>='a'&& ch<='z'|| ch>='A'&& ch<='Z')//取出标识符或者是关键词
{
k=-1;
while(true)//取出的单词长度不超过Wmaxlen,如果超过,则其后的字符无效
{
if((++k)<Wmaxlen)//(++k)为了使取出的单词最长为WMaxlen
{
Word[k]=ch;
ch=GetChar(scult);
}
if (!(ch>='a'&& ch<='z'|| ch>='A'&& ch<='Z'||ch>='0' && ch<='9'||ch=='_'))
break; //如果取出的当前的字符不是字母或是数字,则此次取单词结束
}
//printf("%c",Word[j]);
Word[++k]='\0';//以'\0'标识取出单词的结束,以方便后面的判断此单词是标识符还是关键词
for (int i=0;i<Wmaxlen;i++)//用来判断取出的当前单词是不是关键词
if (strcmp(Word,KEY[i])==0)
{
flag=true;
break;
}
if (flag)
Fbuffer1[ipFBuffer].num=1; //如果是关键词,则把此单词的类型定义为1型
else
Fbuffer1[ipFBuffer].num=2; //否则是标识符,其类型为2
for (int j=0;j<=k;j++)
Fbuffer1[ipFBuffer].value[j]=Word[j];
ipFBuffer=ipFBuffer+1;
}
//printf("输出%c",ch);
else if (ch>='0' && ch<='9') //判断是不是为整数
{ k=-1;
Word[++k]=ch;
ch=GetChar(scult);
while(true)//如果是数字,则一直接受,且定义它的类型为3
if(ch>='0' && ch<='9')
{
Word[++k]=ch;
ch=GetChar(scult);
}
else //不是数字则跳出循环
{
Fbuffer1[ipFBuffer].num=3;
for (int j=0;j<=k;j++)
Fbuffer1[ipFBuffer].value[j]=Word[j];
ipFBuffer=ipFBuffer+1;
break;}
}
else if (pt(ch)==2)//取出是运算符号的单词
{
k=-1;
Word[++k]=ch;
ch=GetChar(scult);
while (ch!='#')
{
Word[++k]=ch;
ch=GetChar(scult);
}
Fbuffer1[ipFBuffer].num=4;
for (int j=0;j<=k;j++)
Fbuffer1[ipFBuffer].value[j]=Word[j];
ipFBuffer=ipFBuffer+1;
}
else if (pt(ch)==3)//判断当前取出的单词是不是界符,如果是界符,则定义其类型为5
{
Fbuffer1[ipFBuffer].num=5;
Fbuffer1[ipFBuffer].value[0]=ch;
ipFBuffer=ipFBuffer+1;
}
ch=GetChar(scult);
}
output();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -