词法分析后的结果
对一个源程序进行词法分析,得到一个二元式,单词的符合,以及对应的内码值

词法分析的过程

程序一开始的时候,先对那些常见标识符和操作符进行加载到一个哈希表中(单纯为了查找方便),并对维护一个唯一的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;
}
}

3509

被折叠的 条评论
为什么被折叠?



