编译实验(一)词法分析
编译原理课程即将结束,开始了在校中最麻烦的实验,编译实验......同在一个系,其他班的编译实验分成好几块,简短的文法,
完成一些小功能,就我们班的老师,撂下一句话:参考书本,把编译器实现了,可以一组两人分工合作。
源代码连接:http://download.csdn.net/download/supersmart_dong/10224159
词法分析流程图:
首先要做的第一步就是写数据结构以及完成单词表。词法分析的任务就是将一段程序代码,分割单词,把单词信息写出来。
例如在代码: while A<2 do A:=A+1; 中进行词法分析得出来结果,(while,关键字) (A,标识符) (<,算符)(2,整数) (do,关键字) (A,标识符)
(:=,算符) (A,标识符)(+,算符) (1,整数) (;,界符) 将代码中单词一个个的取出来进行分析便是词法分析的任务。输出内容是符号表文件和
token文件。
单词表如下图:
单词 |
编码 |
单词 |
编码 |
单词 |
编码 |
单词 |
编码 |
end |
1 |
or |
11 |
( |
21 |
:= |
31 |
begin |
2 |
program |
12 |
) |
22 |
= |
32 |
bool |
3 |
real |
13 |
+ |
23 |
<= |
33 |
do |
4 |
then |
14 |
- |
24 |
< |
34 |
else |
5 |
true |
15 |
* |
25 |
<> |
35 |
end |
6 |
var |
16 |
/ |
26 |
> |
36 |
false |
7 |
while |
17 |
. |
27 |
>= |
37 |
if |
8 |
标识符 |
18 |
, |
28 |
||
integer |
9 |
整数 |
19 |
: |
29 |
||
not |
10 |
实数 |
20 |
; |
30 |
单词表可以用一维对象数组实现,根据编码或者数组索引来判断该单词是不是关键字还是算符或界符。
之后写一些判断的函数,判断是否是关键字,是否是数字,是否是算符,是否是界符
然后按照流程来,读取文件,一个字符一个字符的读,如果读到第i=0个字符是字母,则读第i+1个,一直读到不是字母或数字为止,
将这i个字符构成一个单词,查询是不是关键字,如果不是则为标识符。如果读到的第i=0个字符是数字,则继续读第i+1个,一直读到不是
字母或数字为止。判断这单词是不是数字(浮点数,整数),如果读到第i=0字符既不是字母也不是数字,则读取下一个字符(记为变量A)和下
两个字符(记为变量B),判断这A或B中有没有算符,判断A是不是界符,如果都不是则为非法字符。像这样读完整个程序结束输出符号表文件。
#include<iostream> #include<string> #include<fstream> #include <cassert> using namespace std; struct WordToken { string name; int code; }; struct WordSymble { string name; // int code; string type; int addr = -1; //符号表位置 int linenum; //行号 }; struct symble { int number; //序号 string type; //类型 string name; //名字 }; #pragma region 单词表 WordToken keyword[] = { { "and", 1 }, { "begin", 2 }, { "bool", 3 }, { "do", 4 }, { "else", 5 }, { "end", 6 }, { "false", 7 }, { "if", 8 }, { "integer", 9 }, { "not", 10 }, { "or", 11 }, { "program", 12 }, { "real", 13 }, { "then", 14 }, { "true", 15 }, { "var", 16 }, { "while", 17 } }; WordToken operatorword[] = { { "+", 23 }, { "-", 24 }, { "*", 25 }, { "/", 26 }, { ">", 31 }, { ":=", 38 }, { "=", 32 }, { "<=", 33 }, { "<", 34 }, { "<>", 35 }, { ">", 36 }, { ">=", 37 } }; WordToken delimeter[] = { { "(", 21 }, { ")", 22 }, { ".", 27 }, { ",", 28 }, { ":", 29 }, { ";", 30 } }; #pragma endregion int iskeyword(string s)//关键字 { int i = 0; if (s != "") { if (((s[0] >= 'A') && (s[0] <= 'Z')) || ((s[0] >= 'a') && (s[0] <= 'z'))) { while (i<17) { if (keyword[i].name == s) { return keyword[i].code; } i++; } return 18; //标识符 } } return -1; } int isoperator(string s)//算符 { int i = 0; if (s != "") { while (i<12) { if (s == operatorword[i].name) { return operatorword[i].code; break; } i++; } } return -1; } int isdelimeter(string s)//界符 { int i = 0; if (s != "") { while (i<6) { if (s == delimeter[i].name) { return delimeter[i].code; break; } i++; } } return -1; } int isdight(string &s, int n)//整数 { int i = 0; int j = 0; string ss; bool a = true; string wrong; while (i< s.length()) { if (j <= 1 && a) { if (s[i] == '.') { j++; } if (((s[i] >= 'A') && (s[i] <= 'Z')) || ((s[i] >= 'a') && (s[i] <= 'z'))) { a = false; } i++; } else { for (int k = 0; k < i - 1; k++) { ss += s[k]; s = ss; } for (int k = i - 1; k < s.length(); k++) { wrong += s[k]; } break; } } if (j == 2 || !a) { cout << "错误行号为" << n + 1 << " "; cout << "错误内容为" << wrong << " "; cout << "错误类型为" << "错误单词" << endl; } if (j == 0) { return 19; } else if (j >= 1) { return 20; } return -1; } int length = 0; extern int line = 0; string word; string text; int k = 0; //wordSysmble个数 1开始 int l = 0; string alltext[100]; WordSymble wss[1000]; symble fuhaobiao[1000]; void get_token() //生成符号表和token { for (; alltext[line] != ""; line++) { text = alltext[line]; length = text.length(); for (int i = 0; i < length; i++) { if (text[i] != ' ') { word = ""; if (((text[i] >= 'A') && (text[i] <= 'Z')) || ((text[i] >= 'a') && (text[i] <= 'z'))) { while (((text[i] >= 'A') && (text[i] <= 'Z')) || ((text[i] >= 'a') && (text[i] <= 'z')) || ((text[i] >= 48) && (text[i] <= 57))) { word += text[i]; i++; } i--; if (iskeyword(word) != -1) { if (iskeyword(word) == 18) { wss[k].name = word; wss[k].code = iskeyword(word); wss[k].type = "标识符"; wss[k].addr = l; wss[k].linenum = line; fuhaobiao[l].name = word; fuhaobiao[l].type = "标识符"; fuhaobiao[l].number = l; l++; k++; } else { wss[k].name = word; wss[k].code = iskeyword(word); wss[k].type = "关键字"; wss[k].linenum = line; k++; } } } else if ((text[i] >= 48) && (text[i] <= 57)) { while (((text[i] >= 48) && (text[i] <= 57)) || (text[i] == '.') || ((text[i] >= 'A') && (text[i] <= 'Z')) || ((text[i] >= 'a') && (text[i] <= 'z'))) { word += text[i]; i++; } i--; int a = isdight(word, line); if (a == 19) { wss[k].name = word; wss[k].code = 19; wss[k].type = "整数"; wss[k].addr = l; wss[k].linenum = line; fuhaobiao[l].name = word; fuhaobiao[l].type = "整数"; fuhaobiao[l].number = l; l++; k++; } else if (a == 20) { wss[k].name = word; wss[k].code = 20; wss[k].type = "浮点数"; wss[k].addr = l; wss[k].linenum = line; fuhaobiao[l].name = word; fuhaobiao[l].type = "浮点数"; fuhaobiao[l].number = l; l++; k++; } } else { word += text[i]; string ss = word; ss += text[i + 1]; if (isoperator(ss) != -1) { word += text[i + 1]; i = i + 1; wss[k].name = word; wss[k].code = isoperator(word); wss[k].type = "算符"; wss[k].linenum = line; k++; } else if (isdelimeter(word) != -1) { wss[k].name = word; wss[k].code = isdelimeter(word); wss[k].type = "界符"; wss[k].linenum = line; k++; } else if (isoperator(word) != -1) { wss[k].name = word; wss[k].code = isoperator(word); wss[k].type = "算符"; wss[k].linenum = line; k++; } else { wss[k].name = word; wss[k].code = 100; wss[k].type = "非法字符"; wss[k].linenum = line; k++; } } } } } } void readtext(string file) { ifstream infile; infile.open(file.data()); //将文件流对象与文件连接起来 assert(infile.is_open()); //若失败,则输出错误消息,并终止程序运行 int i = 0; string s; while (getline(infile, s)) { alltext[i] += s; i++; } infile.close(); } void printReadtext(string url = "D: / a.txt") { readtext(url); cout << "程序如下:" << endl; for (int i = 0; alltext[i] != ""; i++) { cout << alltext[i] << endl; } cout << endl; cout << "下面进行词法分析" << endl; cout << endl; get_token(); } void printTokenResult() { int j = 0; cout << endl; while (wss[j].name != "") { cout << "(" << wss[j].name << "," << wss[j].code << "," << wss[j].type << "," << wss[j].addr << "," << wss[j].linenum << ")" << endl; j++; } j = 0; cout << endl; cout << "符号表为" << endl; while (fuhaobiao[j].name != "") { cout << "(" << fuhaobiao[j].number << "," << fuhaobiao[j].name << "," << fuhaobiao[j].type << ")" << endl; j++; } cout << endl; }
部分输出结果如图所示:
编译实验(一)词法分析相关推荐
- 编译原理实验:词法分析
编译原理实验:词法分析 1. 实验题目:词法分析 实验目的 实验内容 实验要求 输入输出 2. 设计思想 3.算法流程 4. 源程序 5. 调试数据 1. 实验题目:词法分析 实验目的 根据PL/0语 ...
- 编译实验(三)目标代码生成
通过词法分析,语法分析,语义分析,最后产生了四元式.而代码生成则是通过四元式来完成.我们先从简单开始做起. 编译实验项目下载链接:http://download.csdn.net/download/s ...
- 编译原理中词法分析的递归下降分析法实例--能被5整除的二进制数---c语言实现
一.前言 又到了一周一度的编译原理实验课,一次实验课上完了,又是大学生必备技能-写实验报告.行了,废话不多说,我直接展现,如何实现编译原理中词法分析的递归下降分析法实例–能被5整除的二进制数的思路.作 ...
- 编译原理中词法分析--部分实现
一.前言 某属于在校大学生,几天前老师布置了一个编译原理作业,将词法分析–部分实现,头疼,众所周之,编译原理是计算机专业中最令人头疼的课程,听懂已经很不容易了,TMD让我用C语言实现 ,头大.经过几个 ...
- 编译原理 C-Minus词法分析(FLEX)
C–源代码词法分析 文章目录 C--源代码词法分析 一.实现目标 二.C-Minus语法 三.Flex Flex简介 Flex正则表达式 Flex安装与使用 Flex文件编写 定义 规则 用户代码 四 ...
- c语言词法分析程序实验报告,实验一词法分析程序设计与实现
实验一 词法分析程序设计与实现 一.实验目的: 加深对词法分析器的工作过程的理解:加强对词法分析方法的掌握:能够采用一种编程语言实现简单的词法分析程序:能够使用自己编写的分析程序对简单的程序段进行词法 ...
- 编译linux源码报错,记录一次Linux内核源码编译实验
记录一次Linux内核源码编译实验 文章目录 记录一次Linux内核源码编译实验 0. 实验环境 1. 选择.下载内核源码 2. 安装必要的依赖软件以及性能要求 3. 解压.配置和编译内核源码 3.1 ...
- 编译原理画出c语言中注释的转化图,编译原理节词法分析DFANFA及其转换.ppt
编译原理节词法分析DFANFA及其转换 Step4 寻找可合并状态 ε ε 0 1 2 0 5 0 1 6 1 3 4 7 ε ε 0 8 9 1 1 0 10 11 0 0 1 1 1 0 12 1 ...
- 编译实验1--词法分析
实验一 词法分析程序 目的和内容 实验目的:通过完成词法分析程序,了解词法分析的过程. 实验内容:用C/C++实现对Pascal的子集程序设计语言的词法识别程序. 实验要求:将该语言的源程序,也就是相 ...
最新文章
- 全球公有云巨头:亚马逊 AWS
- Java获取当前路径和读取文件
- [shiro] - 怎样使用shiro?
- C#委托及事件 详解(讲得比较透彻)
- 2021-03-12 Python基础核心概念 变量和简单数据类型
- BZOJ 1296 粉刷匠(分组背包套DP)
- PaddlePaddle开源平台的应用
- C语言计算总成绩和平均成绩
- 四大经典大数据应用案例解析
- html艺术字在线制作,超全的免费图标字体(在线图标字体制作)
- mt950报文解析_MT9**报文学习
- OpenCV python 轮廓的极值点
- 线性代数知识点总结——矩阵乘法、矩阵运算与性质、矩阵微积分
- 文件上传漏洞---Web渗透学习
- 将MYS_SAM9X5改为dataflash启动
- 四步教你用网站源码建站
- java天眼培训_Java天眼大型分布式跟踪系统 附带源码_IT教程网
- 如何在 R 中计算 Cramer V
- 【103期分享】4款小清新PPT模板免费下载
- 【注意】加密与解密工具新年大礼包2007光盘提供下载