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

📄 词法分析.cpp

📁 主要是编译器中词法分析原理的简单实现
💻 CPP
字号:
// 词法分析.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "cifa.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>

//字母表
char letter[52] = {'a','b','c','d','e','f','g','h','i','j','k','l','m',
				   'n','o','p','q','r','s','t','u','v','w','x','y','z',					
				   'A','B','C','D','E','F','G','H','I','J','K','L','M',
				   'N','O','P','Q','R','S','T','U','V','W','X','Y','Z'
};

//关键字表
char* keyword[11] = {"begin","end","if","then","else","for",
					 "do","while","and","or","not"
};

//数字表
char number[10]={'0','1','2','3','4','5','6','7','8','9'};

//存放已经分析字符的缓冲区
char buff[10];


//将缓冲置为空
void setNull()
{
	for(int i=0; i<=9; i++)
		buff[i] = '#';
}

//判断是否为空格,回车,换行
bool isSpace(char ch)
{
	bool succ = false;
	if(ch==' '||ch=='\n'||ch=='\r')
		succ = true;
	return succ;
}

//判断是否为字母
bool isLetter(char ch)
{
	bool succ = false;
	for(int i=0; i<52; i++)
		if(ch==letter[i])
			succ = true;
	return succ;
}

//判断是否为数字
bool isNumber(char ch)
{
	bool succ = false;
	for(int i=0; i<10; i++)
		if(ch==number[i])
			succ = true;
	return succ;
}

//判断是否为保留字
int isKeyword(const char* str){
	int succ = 0;
	for(int i=0; i<11; i++)
		if(strcmp(str,keyword[i])==0){
			succ = i+1;
			break;
		}
	return succ;
}

//将字符转统一换为小写
char getLetter(FILE *fp)
{
	return tolower(fgetc(fp));
}

//出错处理
void Error(FILE *fp, char ch)
{
	fprintf(fp, "Error occur:\n");
	fprintf(fp, "%c...\n", ch);
	fprintf(fp, "^\n");
}

//输出分析结果
void Print(int type,char* b)
{
	printf("<%d,",type);
	printf("%s",b);
	printf(">\n");
}

//词法分析过程
void Analysis(FILE *infile, FILE *outfile)
{
	char ch;
	int i,isKey;
	do{

		//首先剔除空格符号
		do{
			ch = getLetter(infile);
			//亦可用系统函数isspace()来实现
		}while(isSpace(ch)); 

		if(isLetter(ch)){
			buff[0] = ch;
			ch = getLetter(infile);
			i = 1;
			while (isLetter(ch) || isNumber(ch)){
			   buff[i] = ch;
			   i++;
		       ch = getLetter(infile);
			}
			buff[i] = '\0';
			fseek(infile,-1,1);
			isKey = isKeyword(buff); 
			if(isKey == 0){
				Print(ID,buff);
				fprintf(outfile, "%d,%s\n", ID, buff); //标识符
			}else{
				Print(isKey,buff);
				fprintf(outfile, "%d,%s\n", isKey, buff); //关键字
			}
		}else{
			if(isNumber(ch)){
				buff[0] = ch;
				ch = getLetter(infile);
				i = 1;
				while (isNumber(ch)){
					buff[i] = ch;
					i++;
					ch = getLetter(infile);
				}
				buff[i] = '\0';
				fseek(infile, -1, 1);
				Print(INT,buff);
				fprintf(outfile, "%d,%s\n", INT, buff);
			}else{
				switch(ch){

				case '<':
				{
					ch = getLetter(infile);
					if(ch == '='){
						Print(LE,"<=");
						fprintf(outfile, "%d,%s\n", LE, "<=");
					}
					else if(ch == '>'){
						Print(NE,"<>");
						fprintf(outfile, "%d,%s\n", NE, "<>");
					}
					else {
						fseek(infile, -1, 1);
						Print(LT,"<");
						fprintf(outfile, "%d,%s\n", LT, "<");
					}
					break;
				}

				case '=':
				{
					Print(EQ,"=");
					fprintf(outfile, "%d,%s\n", EQ, "=");
					break;
				}

				case '>':
				{
					ch = getLetter(infile);
					if (ch == '='){
						Print(GE,">=");
						fprintf(outfile, "%d,%s\n", GE, ">=");
					}else{
						fseek(infile, -1, 1);
						Print(GT,">");
						fprintf(outfile, "%d,%s\n", GT, ">");
					}
					break;
				}

				case ':':
				{
					ch = getLetter(infile);
					if (ch == '=') {
						Print(FUZHI,":=");
						fprintf(outfile, "%d,%s\n", FUZHI, ":=");
					}else{
						fseek(infile, -1, 1);
						Print(MAOHAO,":");
						fprintf(outfile, "%d,%s\n", MAOHAO, ":");
					}
					break;
				}
				
				case '/':
				{
					ch = getLetter(infile);
					if (ch == '*') {
						Print(ZHUSHI_BEGIN,"/*");
						fprintf(outfile, "%d,%s\n", ZHUSHI_BEGIN, "/*");
						char zhushi[20];
						int j=0;
						ch = getLetter(infile);
						while(ch!='*'){ //注释的内容
							if(ch!='\r'&&ch!='\n'){
								zhushi[j]=ch;
								j++;
							}
							ch = getLetter(infile);
						}
						zhushi[j]='\0';
						fseek(infile, -1, 1);
		
						Print(ZHUSHI_CONTENT,zhushi);
						fprintf(outfile, "%d,%s\n", ZHUSHI_CONTENT, zhushi);

					}else{
						fseek(infile, -1, 1);
						Print(XIESHU,"/");
						fprintf(outfile, "%d,%s\n", XIESHU, "/");
					}
					break;
				}

				case '+':
				{
					Print(JIAHAO,"+");
					fprintf(outfile, "%d,%s\n", JIAHAO, "+");
					break;
				}
				
				case '-':
				{
					Print(JIANHAO,"-");
				    fprintf(outfile, "%d,%s\n", JIANHAO, "-");
					break;
				}
				
				case '*':
				{
					ch = getLetter(infile);
					if (ch == '/') {
						Print(ZHUSHI_END,"*/");
						fprintf(outfile, "%d,%s\n", ZHUSHI_END, "*/");
					}else{
						fseek(infile, -1, 1);
						Print(CHENHAO,"*");
						fprintf(outfile, "%d,%s\n", CHENHAO, "*");
					}
					break;
				}
				
				case ';':
				{
					Print(FENHAO,";");
					fprintf(outfile, "%d,%s\n", FENHAO, ";");
					break;
				}
				
				case '(':
				{
					Print(ZUOKUOHAO,"(");
					fprintf(outfile, "%d,%s\n", ZUOKUOHAO, "(");	
					break;
				}

				case ')':
				{
					Print(YOUKUOHAO,")");
					fprintf(outfile, "%d,%s\n", YOUKUOHAO, ")");
					break;
				}
				
				default:
				{
					if(ch != EOF){
						Print(ERROR,"error");
						Error(outfile, ch);
					}
					break;
				}
			}
         }
       } 
     }while(ch != EOF);
}

//主函数
int main(int argc, char* argv[])
{
	FILE *infile, *outfile;

	printf("***********************************************************************\n");
	printf("***********************************************************************\n");
	printf("**  <文法描述>                                                       **\n");
	printf("**   1:<标识符>→字母︱ <标识符>字母︱ <标识符>数字                  **\n");
	printf("**   2:<无符号整数>→数字︱ <无符号整数>数字                         **\n");
	printf("**   3:<单字符分界符> →+ ︱- ︱* ︱; ︱(︱)                        **\n");
	printf("**   4:<双字符分界符>→<大于>=︱<小于>=︱<小于>>︱<冒号>=︱<斜竖>*   **\n");
	printf("**   5:<小于>→<                                                     **\n"); 
	printf("**   6:<等于>→=                                                     **\n");
	printf("**   7:<大于>→>                                                     **\n");
	printf("**   8:<冒号> →:                                                    **\n");
	printf("**   9:<斜竖> →/                                                    **\n");
	printf("**   保留字:begin end if then else for do while and or not           **\n");
	printf("***********************************************************************\n");

	int c = 0;	

	do{
		printf("\n***********************************************************************\n");		
		printf("\n请选择:1->开始词法分析  2->退出\n");
		scanf("%d",&c);
		if(c==1){
			char in[20],out[20]; 
			do{
				printf("\n请输入需要分析的源文件路径:");
				scanf("%s",&in);
				printf("\n请输入保存分析结果的文件路径:");
				scanf("%s",&out);
				infile = fopen(in, "r");
				outfile = fopen(out, "w");	
				if(infile==NULL) 
					printf("\n出错:未找到源文件,请再次输入源文件路径!\n\n");
			}while(infile==NULL);

			printf("\n下面是文件%s中文法的词法分析结果:\n\n",in);
			
			Analysis(infile, outfile);
			fprintf(outfile, "0,#");
			fclose(infile);
			fclose(outfile);
			
			printf("\n词法分析已经结束,分析结果已经写到目录下的%s文件!\n",out);	
		}else if(c==2)
			break;
		else printf("请选择正确选项!\n");
	}while(true);

	return 0;
}

⌨️ 快捷键说明

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