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

📄 scaner.cpp

📁 完整的编译器
💻 CPP
字号:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
int label;//Token行数计数

// 初始化函数
void init()
{          
	label=0;
char *key[]={" ","and", "array", "begin", "bool",  "call", "case",	"char",  "constant", "do", "else",
      "end", "false","for","if", "input",  "integer", "not", "of","or", "output",  "procedure",  "program", 
	  "read",   "real",   "repeat",  "set",   "then",  "to",   "true","until",	"var",    "while",    "write", 
	  "symbol",    "intconst",  "realconst",	"charconst",  "'",   "(",	  ")",    "*",   "*/",	"+",     ",",  
	  "-",   ".",     "..",        "/",	"/*",   ":",   ":=",    ";",    "<",   "<=",	"<>",     "=",   ">",     ">=",  
	  "[",     "]",	}; 				//Simple语言单词编码,60 个

    FILE *fp;
    fp=fopen("word.txt","w");
    for(int i=1;i<=60;i++)
       fprintf(fp,"%d\t\t\t%d\t\t\t%s\n",i,i,key[i]);
    fclose(fp);               //初始化单词表字表


	fp=fopen("symble.txt","w");
	fclose(fp);				//建立符号表


    fp=fopen("token.txt","w");
    fclose(fp);               //建立输出文件token串
	//printf("test.txt为simple语言的测试文件,请在下面输入\n");
}


//根据不同命令查表或造表函数

int find(char *buf,int type,int command)
{             
    int number=0;
    FILE *fp;

	int snum;
	int stype;
	char sname[30];
    int i=0;
    switch(type)
    {
        case 1: fp=fopen("word.txt","r");
			break;
        case 2: fp=fopen("symble.txt","r");	
			break;
        case 3: fp=fopen("symble.txt","r");		
			break;
      
    }

		while(!feof(fp)) 
	{	
		fscanf(fp,"%d%d%s",&snum,&stype,sname); /////////////
		if(!feof(fp)) 
			number++;		
		if(strcmp(sname,buf)==0)
        {  
		    fclose(fp);
			return(number);       ///若找到,返回在相应表中的序号
        }
	
	}
	    fclose(fp); 	
     if(command==1)				//1不造入不表,2则造入表
     {   

		 return(0);                //找不到,当只需查表,返回0,否则还需造表
     }
     switch(type)
     {
         case 1: fp=fopen("word.txt","a");break;
         case 2: fp=fopen("symble.txt","a");
			     fprintf(fp,"%d\t\t\t%d\t\t\t%s\n",number+1,34,buf);
				 
				 break;//标识符
         case 3: fp=fopen("symble.txt","a");
			     fprintf(fp,"%d\t\t\t%d\t\t\t%s\n",number+1,35,buf);
				 break;        
     }

     fclose(fp);
     return(number+1);             //造表时,将字符串添加到表尾并返回序号值
}

//数字串处理函数



void cs_manage(char *buffer)
{             
    FILE *fp;
	int result;
    result=find(buffer,3,2);      //先查常数表,若找不到则造入常数表并返回序号值
    fp=fopen("token.txt","a");
	fprintf(fp,"%d\t%s\t%d\t%d\n",++label,buffer,35,result);
	fclose(fp);               //写入输出文件
} 
//字符串处理函数

void ch_manage(char *buffer)
{                     
    FILE *fp;
    int result;
    result=find(buffer,1,1);           //先查单词字表
    fp=fopen("token.txt","a");
    if(result!=0)
       fprintf(fp,"%d\t%s\t%d\t%d\n",++label,buffer,result,-1);    //若找到,写入输出文件
    else
    {
        result=find(buffer,2,2);       //若找不到,则非关键字,查标识符表,还找不到则造入标识符表
        fprintf(fp,"%d\t%s\t%d\t%d\n",++label,buffer,34,result);

    }                                 //写入输出文件
    fclose(fp);
} 
//出错处理函数

void er_manage(char error,int lineno)
{                 
    printf("\nerror: %c ,line %d",error,lineno);    //报告出错符号和所在行数
}


//扫描程序

void scanner()
{            
    FILE *fpin,*fpout;
  //  char filename[20];
    char ch;
	char array[30];
    char *word;
    int i=0,line=1;
    int count,result,errorno=0;

//	printf("\nthe file name:");
  //  scanf("%s","filename);
    if((fpin=fopen("test.txt","r"))==NULL)
    {
        printf("cannot open file");
        return;
    }
    ch=fgetc(fpin);
    while(ch!=EOF)
    {                 //按字符依次扫描源程序,直至结束
        i=0;
        if(((ch>='A')&&(ch<='Z'))||((ch>='a')&&(ch<='z'))||(ch==-1))
        {           //以字母开头
            while(((ch>='A')&&(ch<='Z'))||((ch>='a')&&(ch<='z'))||(ch==-1)||((ch>='0')&&(ch<='9')))
            {
                array[i++]=ch;
                ch=fgetc(fpin);
            }
            word=(char *)malloc((i+1)*sizeof(char));
			memcpy(word,array,i);
			word[i]='\0';
            ch_manage(word);
            if(ch!=EOF)
			   fseek(fpin,-1L,SEEK_CUR);
        }
        else if(ch>='0'&&ch<='9') //以数字开头
        {         
            while(ch>='0'&&ch<='9')
            {
                array[i++]=ch;
                ch=fgetc(fpin);
            }
            word=(char *)malloc((i+1)*sizeof(char));
			memcpy(word,array,i);
			word[i]='\0';
            cs_manage(word);
            if(ch!=EOF)
			   fseek(fpin,-1L,SEEK_CUR);
        }
        else if((ch==' ')||(ch=='\t'))
			;           //消除空格符和水平制表符
		else if(ch=='\n')
			line++;           //消除回车并记录行数
		else if(ch=='/')
        {                 //消除注释
			ch=fgetc(fpin);
			
			 if(ch!='*')
            {              //若为除号,写入输出文件
                fpout=fopen("token.txt","a");
				fprintf(fpout,"%d\t%s\t%d\t%d\n",++label,word,48,-1);
                fclose(fpout);
				fseek(fpin,-1L,SEEK_CUR);
			}
			else if(ch=='*')
			{              //若为注释的开始,消除包含在里面的所有字符
				count=0;
				ch=fgetc(fpin);
				while(count!=2)
                {          //当扫描到‘*’且紧接着下一个字符为‘/’才是注释的结束
					count=0;
					while(ch!='*')
						ch=fgetc(fpin);
					count++;
					ch=fgetc(fpin);
					if(ch=='/')
						count++;
					else
						ch=fgetc(fpin);
				}
			}	

		}

		else
        {         //首字符为其它字符,即运算限界符或非法字符
            array[0]=ch;
            ch=fgetc(fpin);       //再读入下一个字符,判断是否为双字符运算、限界符
            if(ch!=EOF)
            {           //若该字符非文件结束符/
                array[1]=ch;
				word=(char *)malloc(3*sizeof(char));
				memcpy(word,array,2);
				word[2]='\0';
                result=find(word,1,1);      //先检索是否为双字符运算、限界符
				if(result==0)
				{                           //若不是
                    word=(char *)malloc(2*sizeof(char));
					memcpy(word,array,1);
					word[1]='\0';
					result=find(word,1,1);      //检索是否为单字符运算、限界符
					if(result==0)
                    {                           //若还不是,则为非法字符
						er_manage(array[0],line);
						errorno++;
						fseek(fpin,-1L,SEEK_CUR);
                    }
                    else
					{     //若为单字符运算、限界符,写入输出文件并将扫描文件指针回退一个字符
						fpout=fopen("token.txt","a");
						fprintf(fpout,"%d\t%s\t%d\t%d\n",++label,word,result,-1);
						fclose(fpout);
						fseek(fpin,-1L,SEEK_CUR);
					}
				}
                else
				{             //若为双字符运算、限界符,写输出文件
					fpout=fopen("token.txt","a");
					fprintf(fpout,"%d\t%s\t%d\t%d\n",++label,word,result,-1);
					fclose(fpout);
				}
            }
            else
			{               //若读入的下一个字符为文件结束符
				word=(char *)malloc(2*sizeof(char));
				memcpy(word,array,1);
				word[1]='\0';
				result=find(word,1,1);       //只考虑是否为单字符运算、限界符
				if(result==0)                //若不是,转出错处理
					er_manage(array[0],line);
				else
				{                            //若是,写输出文件
					fpout=fopen("token.txt","a");
					fprintf(fpout,"%d\t%s\t%d\t%s\n",++label,word,result,-1);
					fclose(fpout);
				}
			}
        }
        ch=fgetc(fpin); 
    }
    fclose(fpin);
	printf("\nThere are %d error(s).\n",errorno);        //报告错误字符个数
    printf("词法分析结束!\n");
}


//主函数

int main()
{           
    init();           //初始化
    scanner();         //扫描源程序
	return 0;
}  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -