⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wawawa.c

📁 的语法非常容易使用EBNF进行重写
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -