编译原理上机实战---词法分析

词法分析

前一段时间一直在忙上机的事情,连续2周上机四次,现在才有时间整理
废话不多说,上思路:

首先我是以这个 类别和种别码 作为标准进行分类。

/*
单词符号	种别码			单词符号	种别码			单词符号	种别码
bengin		1				if			2				then		3
while		4				do			5				end			6
main		7				int			8				float		9
for			10				else		11				double		12
char		13				break		14				continue	15
标识符		16				整数			17				+			18
-			19				*			20				#			21
%			22				!=			23				<			24
<>			25				<=			26				>			27
>=			28				=			29				==			30
;			31				(			32				)			33
!			34				/			35				"			36
*/

当然也可以进行添加 ,只是需要在switch-case里面添加对应的case而已;

写代码的时候需要注意的是 ,分析每一个类别是否要进入main里面的分析循环

代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define _KEY_WORD_END "waiting for your expanding" /*定义结束关键字*/ 
#define MAX_SIZE 225
typedef struct {
	int typenum;
	char *word;
}WORD; 

WORD *scanner();			//词法扫描函数,获得一个单词
char m_getch();
void  getbc();
void concat();
int letter();
int digit();
int reserve();
void retract();
char *dtb();
 

char input[MAX_SIZE];		//输入缓冲区
char token[MAX_SIZE]="";		//单词缓冲区
int p_input;				//输入缓冲区指针
int p_token;				//单词缓冲区指针

/*
单词符号	种别码			单词符号	种别码			单词符号	种别码
bengin		1				if			2				then		3
while		4				do			5				end			6
main		7				int			8				float		9
for			10				else		11				double		12
char		13				break		14				continue	15
标识符		16				整数		17				+			18
-			19				*			20				#			21
%			22				!=			23				<			24
<>			25				<=			26				>			27
>=			28				=			29				==			30
;			31				(			32				)			33
!			34				/			35				"			36

程序能识别注释,且将其过滤掉 
*/
char ch;					//当前读入字符
char * rwtab[] = {"begin","if","then","while","do","end","main","int","float","for","else","double","char","break","continue","printf"} ;
 
int main(){
	
	int over = 1;
	WORD * oneword = new WORD;//已经测试可以使用 new
	printf("Enter your words(end with $):\n");
	scanf("%[^$]s",input); 
	p_input = 0;
	printf("\nYour words : \n%s\n",input);
	while(over < 1000 && over != -1){		
		oneword = scanner();	//获得一个单词 		
		if(oneword->typenum < 1000)
			printf("(% d, % s)\n",oneword->typenum,oneword->word);//打印种别码和自生的值
		over = oneword->typenum;			
	}
	printf("\n press $ to exit:");
	scanf("%[^$]s",input);

	return 0;
} 

char m_getch(){					//从输入缓存区读取一个字符到ch中 
	ch  = input[p_input];
	p_input = p_input + 1;
//	printf("-------%s\n",input);
	return (ch);
} 

void getbc(){					//去掉空白部分 
	while(ch==' '||ch == 10){
		ch = input[p_input];
		p_input += 1;
	}
} 

void concat(){					//拼接单词 
	token[p_token] = ch;	
	p_token += 1;
	token[p_token] = '\0';
} 

int letter(){					//判断是字母 
	if(ch >= 'a'&&ch <= 'z'||ch >= 'A'&&ch <= 'Z') return 1;
	return 0; 
} 

int digit(){					//判断是数字 
	if(ch >= '0'&&ch <= '9')return 1;
	else return 0;
}

int reserve(){					//检索关键字表格 
	int i = 0;
	while(strcmp(rwtab[i],_KEY_WORD_END)){		
		if(!strcmp(rwtab[i],token)){
			return (i + 1);
		}
		if(i>strlen(*rwtab)) break;
		i = i + 1;
	}
	return 16;
}

void retract(){					//回退一个字符
	p_input = p_input - 1; 
} 

char *dbt(){					//数字转换成二进制
	return NULL;
} 

WORD *scanner(){
	WORD *myword = new WORD;
	myword->typenum = 10;
	myword->word = "";
	p_token = 0;
	m_getch();
	getbc();
		
	if(letter()){
		while(letter()||digit()){
			concat();		//拼接单词 
			m_getch();		//从输入缓存区读取一个字符到ch中 
		}
		retract();			//回退一个字符
		myword->typenum = reserve();
		myword->word = token;
		return (myword);		
	}
	else if(digit()){
		while(digit()){
			concat();
			m_getch();
		}
		retract();
		myword->typenum = 17;
		myword->word = token;
		return (myword);
	}
	else switch(ch){
		case '+':	myword->typenum = 18;
					myword->word = "+";
					return (myword);
					break;
		case '-':	myword->typenum = 19;
					myword->word = "-";
					return (myword);
					break;
		case '*':	myword->typenum = 20;
					myword->word = "*";
					return (myword);
					break;
		case '#':	myword->typenum = 21;
					myword->word = "#";
					return (myword);
					break;
		case '%':	myword->typenum = 22;
					myword->word = "%";
					return (myword);
					break;
		case ';':	myword->typenum = 31;
					myword->word = ";";
					return (myword);
					break;
		case '(':	myword->typenum = 32;
					myword->word = "(";
					return (myword);
					break;
		case ')':	myword->typenum = 33;
					myword->word = ")";
					return (myword);
					break;
		case '!':	m_getch();
					if(ch == '='){
						myword->typenum = 23;
						myword->word = "!=";
						return (myword);
					}
					retract();
					myword->typenum = 34;
					myword->word = "!";
					return (myword);
					break;
		case '<':	m_getch();
					if(ch == '='){
						myword->typenum = 26;
						myword->word = "<=";
						return (myword);
					}
					if(ch == '>'){
						myword->typenum = 25;
						myword->word = "<>";
						return (myword);
					}
					retract();
					myword->typenum = 24;
					myword->word = "<";
					return (myword);
					break;
		case '>':	m_getch();
					if(ch == '='){
						myword->typenum = 28;
						myword->word = ">=";
						return (myword);
					}
					retract();
					myword->typenum = 27;
					myword->word = ">";
					return (myword);
					break;
		case '=':	m_getch();
					if(ch == '='){
						myword->typenum = 30;
						myword->word = "==";
						return (myword);
					}
					retract();
					myword->typenum = 29;
					myword->word = "=";
					return (myword);
					break;
		case'\0': myword->typenum=1000;			//当读取到最后一个字符串的时候 ,为 \0 ,程序会当成无法辨别的程序,故而需要一个case来处理 
                  myword->word="OVER";
                  return(myword);
                  break;
        case '/': m_getch();
    			  if(ch == '*'){
    			  	while(1){
    			  		m_getch();
    			  		if(ch == '*'){
    			  			m_getch();
    			  			if(ch == '/') 
								break;
						}
					  }
					myword->typenum = 1000;
					myword->word = NULL;
					return (myword);
				  }
				  else if(ch == '/'){
				  	while(1){
				  		m_getch();
						if(ch == '\n')
							break; 
					}
					myword->typenum = 1000;
					myword->word = NULL;
					return (myword);
				  }
				  retract();
				  myword->typenum = 35;
				  myword->word = "/";
				  return (myword);
				break;
		case '"': myword->typenum = 36;
		
				  myword->word = " “";
				  return (myword);
				  break;
		default: myword->typenum = -1;
				 myword->word = "ERROR";
				 return (myword);
	}
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Python小叮当

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值