词法分析器的设计(c++实现)

词法分析器的设计(c++实现)

读前必看,此篇词法分析器设计。
第一部分传送门:待更新



步骤

用 Visual C++作为实验开发环境,创建一个Win32 Console Application工程,工程名为你的学号,添加三个文件:
(1)存储结构的定义:以LexerDef.h为文件名;
(2)基本操作和算法的定义:以LexerAlgo.h为文件名;
(3)调用基本操作的主程序:以LexerMain.cpp为文件名。
编写程序:
(1)文件LexerDef.h定义单词符号的二元组结构、全局变量、关键字表的结束标志等。
(2)文件LexerAlgo.h实现词法扫描算法scanner及其所需的各种基本操作算法。
(3)文件LexerMain.cpp调用scanner算法,实现词法分析器的功能。

代码

// LexerDef.h
// An highlighted block
#define  _KEY_WORD_END "waiting for your expanding"   //定义关键字结束标志

/*单词二元组的结构,可以根据需要继续扩充*/
typedef struct
{
    int typenum;
    char *word;
}WORD;
// LexerAlgo.h
// An highlighted block
#include "LexerDef.h"

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

char ch;                //当前读入字符
// 可扩充的关键字数组 
char * rwtab[] = {"begin", "if", "then", "while", "do", "end", _KEY_WORD_END};

// 从缓冲区读取一个字符到 ch中
char m_getch() {
	ch = input[p_input];
	p_input = p_input + 1;
	return (ch);
}
// 去掉空白符号
void getbc(){
	while(ch == ' ' || ch == 10){
		ch = input[p_input];
		p_input = p_input + 1;
	}
}
// 拼接单词
void concat(){
	token[p_token] = ch;
	p_token = p_token + 1;
	token[p_token] = '\0';
} 
// 判断是否为字母
int letter() {
	if(ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z') return 1;
	else 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;
		}
		i = i+1;
	}
	return 10;
} 
// 回退一个字符
void retract(){
	p_input = p_input-1;
} 
// 数字转换为二进制
char * dtb(){
	return NULL;
} 

/*
词法扫描程序 
*/

WORD * scaner(){
	WORD * myword = new WORD;
	myword -> typenum = 10;
	myword -> word = "";
	p_token = 0;
	m_getch();
	getbc();
	if(letter()){
		while(letter() || digit()){
			concat();
			m_getch();
		}
		retract();
		myword -> typenum = reserve();
		myword -> word = token;
		return(myword);
	}
	else if(digit()){
		while(digit()){
			concat();
			m_getch();
		}
		retract();
		myword -> typenum = 20;
		myword -> word = token;
		return(myword);
	}
	else switch(ch){
		case '=': m_getch();
			if(ch == '='){
				myword -> typenum = 39;
				myword -> word = "==";
				return(myword);
			}
			retract();
			myword -> typenum = 21;
			myword -> word = "=";
			return(myword);
			break;
		case '+': myword->typenum = 22;
            myword->word = "+";
            return(myword);
            break;
        case '-': myword->typenum = 23;
            myword->word = "-";
            return(myword);
            break;
        case '*': myword->typenum = 24;
            myword->word = "*";
            return(myword);
            break;
        case '/': myword->typenum = 25;
            myword->word = "/";
            return(myword);
            break;
        case '(': myword->typenum = 26;
            myword->word = "(";
            return(myword);
            break;

        case ')': myword->typenum = 27;
            myword->word = ")";
            return(myword);
            break;
        case '[': myword->typenum = 28;
            myword->word = "[";
            return(myword);
            break;

        case ']': myword->typenum = 29;
            myword->word = "]";
            return(myword);
            break;

        case '{': myword->typenum = 30;
            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 ';': myword->typenum = 34;
            myword->word = ";";
            return(myword);
            break;

        case '>': m_getch();
            if(ch == '=')
            {
            	myword->typenum = 37;
                myword->word = ">=";
                return(myword);
            }
            retract();
            myword->typenum = 35;
        	myword->word = ">";
            return(myword);
            break;

        case '<': m_getch();
            if(ch == '=')
            {
                myword->typenum = 38;
                myword->word = "<=";
                return(myword);
            }
            retract();
            myword->typenum = 36;
            myword->word = "<";
            return(myword);
            break;

        case '!': m_getch();
            if(ch == '=')
            {
                myword->typenum = 40;
                myword->word = "!=";
                return(myword);
            }
            retract();
            myword->typenum = -1;
            myword->word = "ERROR";
            return(myword);
            break;

        case '\0': myword->typenum = 1000;
            myword->word = "OVER";
            return(myword);
            break;
        default: myword->typenum = -1;
            myword->word = "ERROR";
            return(myword);
	}
}
// LexerMain.cpp
// An highlighted block
WORD *scaner();  //词法扫描函数,获得一个单词

int main()
{
    int over = 1;
    WORD *oneword = new WORD;
    printf("Enter Your words (end with #):");
    scanf("%[^#]s", input); //读入源程序字符到缓冲区,以#结束,允许多行输入

    p_input = 0;
    printf("Your words: \n %s \n", input);

    //对源程序进行分析,直至结束符#
    while(over < 1000 && over != -1)
    {
        oneword = scaner();  //获取新单词
        if (oneword->typenum < 1000)
            printf("%d, %s", oneword->typenum, oneword->word);  //打印种别码和单词自身的值
        over = oneword->typenum;
    }
    printf("\npress # to exit:");   //按#退出程序
    scanf("%[^#]s", input);
    return 0;
}

运行截图

(1)源程序begin x:=9; if x>0 then x:=2*x+1/3; end #
在这里插入图片描述
(2)输入一段此简单语言的源程序,且包含以下单词符号while <> -
在这里插入图片描述
好了,到这里已经结束了,这是词法分析器的实现,有想了解详细过程和原理的可以留言或私信我。

  • 5
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值