编译原理,词法分析器

词法分析后的结果

对一个源程序进行词法分析,得到一个二元式,单词的符合,以及对应的内码值
在这里插入图片描述

词法分析的过程

在这里插入图片描述
程序一开始的时候,先对那些常见标识符和操作符进行加载到一个哈希表中(单纯为了查找方便),并对维护一个唯一的id映射的关系

在这里插入图片描述

// 初始化
void init() {
	for (auto& e : keyBuf) keyWord[e] = ++idx;
	for (auto& e : operBuf)	oper[e] = ++idx;
	operand = ++idx;
	tag = ++idx;
}

然后从事先准备好的解析文件中,将里面的程序部分按行读取,得到一个字符串

	ifstream fp(fileName);
	string rbuf;

	init();
	while (getline(fp, rbuf)) {
		buf += rbuf + "\n";
	}

然后就可以进行解析了,按照顺序在字符串中从前向后进行解析,遇到字母就记录一下,如果遇到空格,符号,数字则需要记录一下,说明当前字母已经构成了一个标识符,维护一个哈希表的映射关系,然后再处理对应的符号或者数字。

词法分析程序

#define _CRT_SECURE_NO_WARNINGS 1


#include <iostream>
#include <fstream>
#include <unordered_map>
#include <string>
#include <vector>

using namespace std;

const string  fileName	=	"text.cpp";
vector<string> keyBuf	= { "int", "if", "else", "while", "do", "return","for" ,"include"};
vector<string> operBuf	= {"#" ,"<", ">", "!=", ">=", "<=", "==", ",", ";", "(", ")", "{", "}", "+", "-", "*", "/", "=" ,"++"};
vector<string> numBuf	= { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };

int		idx;							// 词法标号
string	buf;							// 源程序
int							operand;	// 操作数
int							tag;		// 标识符
unordered_map<string, int>	keyWord;	// 关键字
unordered_map<string, int>	oper;		// 操作符

void init();			// 初始化
void analyse();			// 词法解析
bool isSpace(char ch);	// 是否为空格,tab,回车
void show(string first, int index);	// 展示

int main() {
	ifstream fp(fileName);
	string rbuf;

	init();
	while (getline(fp, rbuf)) {
		buf += rbuf + "\n";
	}
	cout << "词法分析器解析源文件: \n\n";
	cout << "==================================================" << endl;
	cout << buf << endl;

	analyse();		// 解析

	fp.close();
	return 0;
}

// 初始化
void init() {
	for (auto& e : keyBuf) keyWord[e] = ++idx;
	for (auto& e : operBuf)	oper[e] = ++idx;
	operand = ++idx;
	tag = ++idx;
}

void show(string first, int index) {
	printf("[ %s -> ( %d , %s )] \n", first.c_str(), index, first.c_str());
}

// 是否为空格,tab,回车
bool isSpace(char ch) {
	return ch == ' ' || ch == '\n' || ch == '\t';
}

// 是否为操作符
bool isOper(char ch) {
	string s(1,ch);
	//if (oper.find(s) != oper.end()) cout << "no find " << s << endl;
	return oper.find(s) != oper.end();
}

// 是否是数字
bool isNum(string& str) {
	for (auto& ch : str) if (ch < '0' || ch > '9') return false;
	return true;
}

// 标识符,数字 解析
void check(string& str) {
	if (str == "") return;

	// 是否为数字
	bool ret = isNum(str);
	if (ret) {
		// number
		show(str, operand);
	}else {
		if (keyWord.find(str) == keyWord.end()) {
			// 标识符
			show(str, tag);
			return;
		}
		show(str, keyWord[str]);
	}
}

// 操作符解析
void checkOper(int& index) {
	int p = index;
	string t;
	for (; p < buf.size(); p++) {
		if (oper.find(t + buf[p]) == oper.end()) break;
		t += buf[p];
	}
	show(t, oper[t]);
	index = p - 1;
}

// 词法解析
void analyse() {
	string str;
	int n = buf.size();

	for (int i = 0; i < n; i++) {
		if (isSpace(buf[i])) {
			check(str);
			str = "";
		}else if (isOper(buf[i])) {
			check(str);
			checkOper(i);
			str = "";
		}else {
			str += buf[i];
		}

		//cout << str << endl;
	}
}
  • 5
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值