合工大 编译原理 实验1

用VC++/VB/JAVA语言实现对C语言子集的源程序进行词法分析。通过输入源程序从左到右对字符串进行扫描和分解,依次输出各个单词的内部编码及单词符号自身值;若遇到错误则显示“Error”,然后跳过错误部分继续显示;同时进行标识符登记符号表的管理。
在这里插入图片描述

#include <iostream>
#include <string.h>
#include <vector>
#include <utility>
using namespace std;
string key[] = { "if", "while", "for", "else","then","do","return" };     //第一类 关键词
char boundary[] = { '[',']',')','(',';' };         //第二类 分节符
char acc[] = { '+','-','*','/'};                   //第三类 算数运算符
string relation[] = { ">=","<=" ,">","<","=","==" }; //第四类 关系运算符
                                                     //第五类常数 第六类标识符
vector<string> ident;  //变量保存
//结果保存
vector<string> word;
vector<pair<int, string>> attribute;
vector<string> type;
vector<pair<int, int>> loc;

bool isDigtal(char a) {
	if (a >= '0' && a <= '9')
		return true;
	else return false;
}

bool isLetter(char a) {
	if (a >= 'a' && a <= 'z')
		return true;
	else return false;
}

bool isChe(char a) {
	if (a == '\n')
		return true;
	else return false;
}

bool isKey(string s) {
	for (int i = 0; i < 7; i++) {
		if (strcmp(s.c_str(), key[i].c_str()) == 0) {
			return true;
		}
	}
	return false;
}
bool isBound(char a) {
	for (int i = 0; i < 5; i++) {
		if (a == boundary[i]) {
			return true;
		}
	}
	return false;
}
bool isAcc(char a) {
	for (int i = 0; i < 4; i++) {
		if (a == acc[i]) {
			return true;
		}
	}
	return false;
}
void LexicalAnalysis(string s) {
	int row = 1, col = 1;
	int len = s.length();
	int i = 0;
	while (i < len) {
		if (isLetter(s[i])) {
			string tmp = "";
			while (isDigtal(s[i]) || isLetter(s[i])) {
				tmp += s[i];
				i++;
			}
			if (isKey(tmp)) {
				word.push_back(tmp);
				attribute.push_back(make_pair(1, tmp));
				type.push_back("关键字");
				loc.push_back(make_pair(row, col));
				col++;
			}
			else {
				int flag = 0;
				for (int j = 0; j < ident.size(); j++) {
					if (strcmp(tmp.c_str(), ident[j].c_str()) == 0) {
						flag = 1;
					}
				}
				if (!flag) {
					ident.push_back(tmp);
				}
				word.push_back(tmp);
				attribute.push_back(make_pair(6, tmp));
				type.push_back("标识符");
				loc.push_back(make_pair(row, col));
				col++;
			}
		}
		else if (isChe(s[i])) {
			row++;
			col = 1;
			i++;
		}
		else if (isDigtal(s[i])) {
			string tmp = "";
			while (isDigtal(s[i])) {
				tmp += s[i];
				i++;
			}
			if (isBound(s[i]) || s[i] == ' ') {
				word.push_back(tmp);
				attribute.push_back(make_pair(5, tmp));
				type.push_back("常数");
				loc.push_back(make_pair(row, col));
				col++;
			}
			else {
				while (isLetter(s[i]) || isDigtal(s[i])) {
					tmp += s[i];
					i++;
				}
				word.push_back(tmp);
				attribute.push_back(make_pair(7, tmp));
				type.push_back("ERROR");
				loc.push_back(make_pair(row, col));
				col++;
			}
		}
		else if (isBound(s[i])) {
			string tmp = "";
			tmp += s[i];
			word.push_back(tmp);
			attribute.push_back(make_pair(2, tmp));
			type.push_back("分界符");
			loc.push_back(make_pair(row, col));
			col++;
			i++;
		}
		else if (s[i] == '>' || s[i] == '<' || s[i] == '=') {
			string tmp = "";
			tmp += s[i];
			i++;
			if  (s[i] == '=') {
				tmp += s[i];
				i++;
			}
			word.push_back(tmp);
			attribute.push_back(make_pair(4, tmp));
			type.push_back("关系运算符");
			loc.push_back(make_pair(row, col));
			col++;
		}
		else if (isAcc(s[i])) {
			string tmp = "";
			tmp += s[i];
			i++;
			if (isLetter(s[i]) || isDigtal(s[i])) {
				word.push_back(tmp);
				attribute.push_back(make_pair(3, tmp));
				type.push_back("算数运算符");
				loc.push_back(make_pair(row, col));
				col++;
			}
			else {
				while (s[i] != ' ' && !isBound(s[i])) {
					tmp += s[i];
					i++;
				}
				word.push_back(tmp);
				attribute.push_back(make_pair(7, tmp));
				type.push_back("ERROR");
				loc.push_back(make_pair(row, col));
				col++;
			}
		}
		else if (s[i] == ' ' || s[i] == '\n') {
		i++;
		}
		else {
			string tmp = "";
			while (s[i] != ' ' && !isBound(s[i])) {
				tmp += s[i];
				i++;
			}
			word.push_back(tmp);
			attribute.push_back(make_pair(7, tmp));
			type.push_back("ERROR");
			loc.push_back(make_pair(row, col));
			col++;
		}
	}
}
int main() {
	string s = "if i=0 then n++;\na<=b3%);\n342342;\njfksjf+jgf3;dfsf459834jifsdjfw;";
	cout << s << endl;
	LexicalAnalysis(s);

	for (int i = 0; i < word.size(); i++) {
		cout << word[i] << "  (" << attribute[i].first << "," << attribute[i].second << ")  " << type[i] << "  (" << loc[i].first << "," << loc[i].second <<")"<< endl;
	}
	return 0;
}
  • 11
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
编译原理 合工大17级 课件 李宏芒老师的课件 包含以下章节 第一章 引论  1.1 什么叫编译程序  1.2 编译过程概述  1.3 编译程序的结构  1.4 编译程序与程序设计环境  1.5 编译程序的生成 第二章 高级语言及其语法描述  2.1 程序语言的定义  2.2 高级语言的一般特性  2.3 程序语言的语法描述 第三章 词法分析  3.1 对于词法分析器的要求  3.2 词法分析器的设计  3.3 正规表达式与有限自动机  3.4 词法分析器的自动产生 第四章 语法分析——自上而下分析  4.1 语法分析器的功能  4.2 自上而下分析面临的问题  4.3 LL(1)分析法  4.4 递归下降分析程序构造  4.5 预测分析程序  4.6 LL(1)分析中的错误处理 第五章 语法分析——自下而上分析  5.1 自下而上分析基本问题  5.2 算符优先分析  5.3 LR分析法  5.4 语法分析器的自动产生工具YACC 第六章 属性文法和语法制导翻译  6.1 属性文法  6.2 基于属性文法的处理方法  6.3 S-属性文法的自下而上计算  6.4 L-属性文法和自顶向下翻译  6.5 自下而上计算继承属性 第七章 语义分析和中间代码产生  7.1 中间语言  7.2 说明语句  7.3 赋值语句的翻译  7.4 布尔表达式的翻译  7.5 控制语句的翻译  7.6 过程调用的处理  7.7 类型检查 第八章 符号表  8.1 符号表的组织与作用  8.2 整理与查找  8.3 名字的作用范围  8.4 符号表的内容 第九章 运行时存储空间组织  9.1 目标程序运行时的活动  9.2 运行时存储器的划分  9.3 静态存储分配  9.4 简单的栈式存储分配  9.5 嵌套过程语言的栈式实现  9.6 堆式动态存储分配 第十章 优化  10.1 概述  10.2 局部优化  10.3 循环优化  *10.4 数据流分析 第十一章 目标代码生成  11.1 基本问题  11.2 目标机器模型  11.3 一个简单的代码生成器  11.4 寄存器分配  11.5 DAG的目标代码  11.6 窥孔优化
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值