词法分析程序(Lexical Analyzer)要求:
- 从左至右扫描构成源程序的字符流
- 识别出有词法意义的单词(Lexemes)
- 返回单词记录(单词类别,单词本身)
- 滤掉空格
- 跳过注释
- 发现词法错误
程序结构:
输入:字符流(什么输入方式,什么数据结构保存)
处理:
–遍历(什么遍历方式)
–词法规则
输出:单词流(什么输出形式)
–二元组
单词类别:
1.标识符(10)
2.无符号数(11)
3.保留字(一词一码)
4.运算符(一词一码)
5.界符(一词一码)
| 
 单词符号  | 
 种别码  | 
 单词符号  | 
 种别码  | 
| 
 begin  | 
 1  | 
 :  | 
 17  | 
| 
 if  | 
 2  | 
 :=  | 
 18  | 
| 
 then  | 
 3  | 
 <  | 
 20  | 
| 
 while  | 
 4  | 
 <=  | 
 21  | 
| 
 do  | 
 5  | 
 <>  | 
 22  | 
| 
 end  | 
 6  | 
 >  | 
 23  | 
| 
 l(l|d)*  | 
 10  | 
 >=  | 
 24  | 
| 
 dd*  | 
 11  | 
 =  | 
 25  | 
| 
 +  | 
 13  | 
 ;  | 
 26  | 
| 
 -  | 
 14  | 
 (  | 
 27  | 
| 
 *  | 
 15  | 
 )  | 
 28  | 
| 
 /  | 
 16  | 
 #  | 
 0  | 
源代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 100
int p=0,syn,n,i; 														//syn用于记录种别码,其为全局变量
char prog[SIZE],ch,token[8];
char *keyword[6]={"begin","then","if","while","do","end"};				//定义关键字数组
void scaner(); 															//将prog数组中的数移到token数组进行比较,更新种别码 
main()
{
	p=0;
	printf("请输入源程序字符串(以'#'结束):\n");
	do{
		ch=getchar();
		prog[p++]=ch;
	}while(ch!='#');													//将键盘输入的字符串录入数组prog
			p=0; 
	do
		{
			scaner();
			switch(syn)
				{
					case -1:printf("词法分析 出错\n");break;
					default :printf("<%d,%s>\n",syn,token);break;
					} 
		}while(syn!=0);													//输入#号,种别码syn为0,循环结束
			printf("词法分析 成功\n"); 
			getchar(); 
}
void scaner()
{ 
	for(n=0;n<8;n++){													//初始化token数组
	token[n]='\0';
	}
	n=0;
	ch=prog[p++];
	while(ch==' '){
		ch=prog[p++];
	} 
	if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){							//判断输入的是否为关键字
	do{
		token[n++]=ch;
		ch=prog[p++];
	}while((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||(ch>='0'&&ch<='9'));
	syn=10; 
	for(n=0;n<6;n++){
		if(strcmp(token,keyword[n])==0)
		syn=n+1;
	}
		p--;
	}
	else if(ch>='0'&&ch<='9'){  										//判断输入的是否为整数常数
		p--;
		do
	{
		token[n++]=prog[p++];
		ch=prog[p];
	}while(ch>='0'&&ch<='9');
		syn=11; 
		return;
	}
	else
	{
		switch(ch)
	{
		case '+':syn=13;token[0]=ch;break;
		case '-':syn=14;token[0]=ch;break;
		case '*':syn=15;token[0]=ch;break;
		case '/':syn=16;token[0]=ch;break;
		case ':':syn=17;token[0]=ch;
		ch=prog[p++];
		if(ch=='='){
			token[1]=ch;syn++;
		}
		else p--;
		break;
		case '<':syn=20;token[0]=ch;
		ch=prog[p++];
		if(ch=='>'){
			token[1]=ch;syn++;
		}
		else if(ch=='='){
			token[1]=ch;syn=syn+2;
		}
		else p--;
		break;
		case '>':syn=23;token[0]=ch;
		ch=prog[p++];
		if(ch=='='){
			token[1]=ch;syn++;
		}
		else 
			p--;
			break;
		case '=':syn=25;token[0]=ch;break;
		case ';':syn=26;token[0]=ch;break;
		case '(':syn=27;token[0]=ch;break;
		case ')':syn=28;token[0]=ch;break;
		case '#':syn=0;token[0]=ch;break; 
		default: printf("词法分析出错! 请检查是否输入非法字符\n");syn=-1;break; 
	}
	}
}
运行结果:

来源:https://www.cnblogs.com/chuichuichui1998/p/11654734.html