📄 wawawa.c
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
//定义全局变量
FILE *fp,*fp1;//指向有进行语法分析的文件
char sym[20]={0};//类别
char s[20]={0};//在涵数中做临时变量数组
char id[20]={0};//若为标志符,存放自身值
int num;//若为整数,存放自身值
int lineno;//行号
int err;//标记何种错误的数字
int count=0;//记录错误出现的次数
int l=0;//记录调用的层次lev
int iftrue=1;
//空格
void nul(int n)
{
int i=0;
for(i=0;i<=n;i++)
printf(" ");
}
void fengexian(int n)//修饰DOS界面的分隔线
{
int i;
nul(l-1);
//printf("||");
for(i=0;i<=n;i++)
printf("-");
//printf("||");
printf("\n");
}
void show()//界面的初始部分
{
fengexian(50);
printf(" 编译原理语法分析实验!\n");
printf(" 作者姓名\n");
fengexian(50);
}
FILE *openfile(char *mode)
{
char tmpfile[20];
FILE *reval=NULL;
while(iftrue)
{
//gets(tmpfile);
scanf("%s",tmpfile);
getchar();
reval=fopen(tmpfile,mode);
if(reval!=NULL) break;
printf("不能打开文件\"%s\",请重新输入:",tmpfile);
iftrue=1;
}
return reval;
}
void get()//取文件中的一个单词
{
char ch;
char str[10];
int i=0;
ch=fgetc(fp);
while(ch==' '||ch=='\n')
{
ch=fgetc(fp);
}
str[i]=ch;
i++;
ch=fgetc(fp);
while(ch!=' '&&ch!='\n')
{
str[i]=ch;
i++;
ch=fgetc(fp);
}
str[i]='\0';
i=0;
strcpy(s,str);
}
void getsym()//取文件中的一组单词
{
get();
lineno=atoi(s);
//printf("%d\n",lineno);
get();
if(strcmp(s,"ident")==0)
{
strcpy(sym,s);
//printf("%s\n",sym);
get();
strcpy(id,s);
//printf("%s\n",id);
}
else if(strcmp(s,"number")==0)
{
strcpy(sym,s);
//printf("%s\n",sym);
get();
num=atoi(s);
//printf("%d\n",num);
}
else
{
strcpy(sym,s);
//printf("%s\n",sym);
}
}
//错误处理
void error(int err)
{
count++;
nul(l);printf(" %d次错误:",count);
switch(err)
{
case 1:printf("%d行 1!-常量说明中\"=\"写成\":=\".\n",lineno);break;
case 2:printf("%d行 2!-常量说明中的\"=\"后应是数字.\n",lineno);break;
case 3:printf("%d行 3!-常量说明中的标识符后应是\"=\".\n",lineno);break;
case 4:printf("%d行 4!-const,var,procedure后应为标识符.\n",lineno);break;
case 5:printf("%d行 5!-漏掉了','或';'.\n",lineno);break;
case 6:printf("%d行 6!-过程说明后的符号不正确(应是语句开始符,或过程定义符).\n",lineno);break;
case 7:printf("%d行 7!-应是语句开始符.\n",lineno);break;
case 8:printf("%d行 8!-程序体内语句部分的后跟符不正确.\n",lineno);break;
case 9:printf("%d行 9!-程序结尾丢了句号'.'.\n",lineno); break;
case 10:printf("%d行 10!-语句之间漏了';'.\n",lineno);break;
case 11:printf("%d行 11!-标识符未说明.\n",lineno); break;
case 12:printf("%d行 12!-赋值语句中,赋值号左部标识符属性应是变量.\n",lineno);break;
case 13:printf("%d行 13!-赋值语句左部标识符后应是赋值号':='.\n",lineno); break;
case 14:printf("%d行 14!-call后应为标识符.\n",lineno); break;
case 15:printf("%d行 15!-call后标识符属性应为过程.\n",lineno); break;
case 16:printf("%d行 16!-条件语句中丢了'then'.\n",lineno);break;
case 17:printf("%d行 17!-丢了'end'或';'.\n",lineno);break;
case 18:printf("%d行 18!-while型循环语句中丢了'do'.\n",lineno); break;
case 19:printf("%d行 19!-语句后的符号不正确.\n",lineno);break;
case 20:printf("%d行 20!-应为关系运算符.\n",lineno); break;
case 21:printf("%d行 21!-表达式内标识符属性不能是过程.\n",lineno);break;
case 22:printf("%d行 22!-表达式中漏掉了右括号')'.\n",lineno);break;
case 23:printf("%d行 23!-因子后的非法符号.\n",lineno);break;
case 24:printf("%d行 24!-表达式的开始符不能是此符号.\n",lineno);break;
case 31:printf("%d行 31!-数越届.\n",lineno);break;
case 32:printf("%d行 32!-read语句括号中的标识符不是变量.\n",lineno);break;
default:printf("错误\n");
}
}
//因子处理
//<因子>::=<标识符>|<无符号整数>|'('<表达式>')'
void factor()
{
void expression();
nul(l);printf(" 因子开始\n");
if(strcmp(sym,"ident")==0)
{//因子是常量或变量
nul(l);printf(" 因子是标识符%s\n",id);
getsym();
}
else if(strcmp(sym,"number")==0)
{//因子是数字
nul(l);printf(" 因子是无符号整数%d\n",num);
getsym();
}
else if(strcmp(sym,"lparen")==0)
{//因子是表达式,标识是以左扩号开始
nul(l);printf(" 因子是表达式%s\n",sym);
getsym();
expression();//表达式处理
if(strcmp(sym,"rparen")==0)
{
nul(l);printf("%s\n",sym);
getsym();
}
else error(22);//表达式中漏掉了右扩号
}
nul(l);printf(" 因子结束\n");
}
//项处理
//<项>::=<因子>{<乘法运算符><因子>}
void term()
{
nul(l);printf(" 项开始\n");
factor();
while(strcmp(sym,"times")==0||strcmp(sym,"slash")==0)
{
nul(l);printf("%s",sym);
getsym();
factor();
}
nul(l);printf(" 项结束\n");
}
//表达式处理
//<表达式>::=[+|-]<项>{<加法运算符><项>}
void expression()
{
nul(l);printf(" 表达式开始\n");
if(strcmp(sym,"plus")==0||strcmp(sym,"minus")==0)
{
nul(l);printf("%s",sym);
getsym();
term();
}
else
{
term();
}
while(strcmp(sym,"plus")==0||strcmp(sym,"minus")==0)
{
nul(l);printf("%s",sym);
getsym();
term();
}
nul(l);printf(" 表达式结束\n");
}
//条件处理
//<条件>::=<表达式><关系运算符><表达式>|ODD<表达式>
void condition()
{
nul(l);printf("条件开始\n");
while(strcmp(sym,"oddsym")==0||strcmp(sym,"plus")==0||strcmp(sym,"minus")==0||strcmp(sym,"lparen")==0||strcmp(sym,"ident")==0||strcmp(sym,"number")==0)
{
if(strcmp(sym,"oddsym")==0)
{
nul(l);printf("%s\n",sym);
expression();
}
else
{
expression();
if(strcmp(sym,"eql")==0||strcmp(sym,"neq")==0||strcmp(sym,"lss")==0||strcmp(sym,"leq")==0||strcmp(sym,"gtr")==0||strcmp(sym,"geq")==0)
{
nul(l);printf("%s\n",sym);
getsym();
expression();
}
else error(20);//应为关系运算符
}
}
nul(l);printf("条件结束\n");
}
//赋值语句处理
//<赋值语句>::=<标识符>:=<表达式>
void FuZhi()
{
nul(l);printf("赋值语句开始 ");
if(strcmp(sym,"ident")==0)
{
nul(l);printf("标识符%s\n",id);
getsym();
if(strcmp(sym,"becomes")==0)
{
nul(l);printf("%s\n",sym);
getsym();
}
else error(13);//赋值语句左部标识符后应是赋值号':='.
expression();
}
nul(l);printf("赋值语句结束 ");
}
//条件语句处理
//<条件语句>::=IF<条件>THEN<语句>
void TiaoJian()
{
void statement();
nul(l);printf("条件语句开始 ");
if(strcmp(sym,"ifsym")==0)
{
nul(l);printf("%s\n",sym);
getsym();
condition();
if(strcmp(sym,"thensym")==0)
{
nul(l);printf("%s\n",sym);
getsym();
}
else error(16);//条件语句中丢了'then'.
statement();
}
nul(l);printf("条件语句结束 ");
}
//当型循环语句处理
//<当型循环语句>::=WHILE<条件>DO<语句>
void DangXingXunHuan()
{
void statement();
nul(l);printf("当型循环语句开始 ");
if(strcmp(sym,"whilesym")==0)
{
nul(l);printf("%s\n",sym);
getsym();
condition();
if(strcmp(sym,"dosym")==0)
{
nul(l);printf("%s\n",sym);
getsym();
statement();
}
else error(18);//while型循环语句中丢了'do'
}
nul(l);printf("当型循环语句结束 ");
}
//过程调用语句处理
//<过程调用语句>::=CALL<标识符>
void GuoChengDiaoYong()
{
nul(l);printf("过程调用语句开始 ");
if(strcmp(sym,"callsym")==0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -