Pascal 语法分析器 简易实现

4 篇文章 0 订阅
订阅专栏
2 篇文章 1 订阅
订阅专栏

目录

前言

一、实现内容

二、实现准备

1.词法分析器

2.自上而下的语法分析(理论)

三、代码节选

 四、测试截图

 


前言

此文仅笔者学习记录,并不是多么高深的东西,而且离完成也过了一段时间(不小心给忘了,汗),不过非常欢迎各种指导建议


 

一、实现内容

PASCAL语言子集(PL/0)词法分析器的设计与实现
PL/0语言的BNF描述(扩充的巴克斯范式表示法)

<prog> → program <id>;<block>
<block> → [<condecl>][<vardecl>][<proc>]<body>
<condecl> → const <const>{,<const>};
<const> → <id>:=<integer>
<vardecl> → var <id>{,<id>};
<proc> → procedure <id>([<id>{,<id>]});<block>{;<proc>}
<body> → begin <statement>{;<statement>}end
<statement> → <id> := <exp>
               |if <lexp> then <statement>[else <statement>]
               |while <lexp> do <statement>
               |call <id>([<exp>{,<exp>}])
               |<body>
               |read (<id>{,<id>})
               |write (<exp>{,<exp>})
<lexp> → <exp> <lop> <exp>|odd <exp>
<exp> → [+|-]<term>{<aop><term>}
<term> → <factor>{<mop><factor>}
<factor>→<id>|<integer>|(<exp>)
<lop> → =|<>|<|<=|>|>=
<aop> → +|-
<mop> → *|/
<id> → l{l|d}   (注:l表示字母)
<integer> → d{d}


注释:
<prog>:程序 ;<block>:块、程序体 ;<condecl>:常量说明 ;<const>:常量;
<vardecl>:变量说明 ;<proc>:分程序 ; <body>:复合语句 ;<statement>:语句;
<exp>:表达式 ;<lexp>:条件 ;<term>:项 ; <factor>:因子 ;<aop>:加法运算符;
<mop>:乘法运算符; <lop>:关系运算符
odd:判断表达式的奇偶性。

要求:

使用循环分支方法实现PL/0语言的词法分析器,该词法分析器能够读入使用PL/0语言书写的源程序,输出单词符号串及其属性到一中间文件中,具有一定的错误处理能力,给出词法错误提示

(需要输出错误所在的行列)


 

二、实现准备

1.词法分析器

要实现语法分析器必须有词法分析器,将一整段代码分割成不同种别编号的单词符号

词法分析器 简易实现

 

2.自上而下的语法分析(理论)

由于题干要求以循环分支的方式实现,因此需要掌握一定的自上而下的语法分析知识(如果对优化感到很麻烦,可以省略)


三、代码节选

  1. "Ana_XXX"即为题干中对应的XXX的语法分析子过程
  2. "IsId()"函数为变量名函数,即识别用户自己定义的变量名
  3. “Reverse()”函数为关键词函数,即对单词符号进行识别,是否为关键词(即while、do.....)
  4. “GetWordArray()”函数将txt文本中的代码进行分割,利用Analysis()函数(词法分析器中有代码,稍做了改变,但算法思想一致)剔除空格识别单词符号,并储存进WordArray数组
  5. fp为文本指针(并非数据类型,只是一种形容),指向当前浏览到的char字符
  6. codefile为char数组,储存txt文本中的代码内容,filelen为codefile数组的字符个数
  7. ReadFile为读文件函数,得到codefile数组和filelen
  8. WordNum仅是一个增量常量(#define WordNum 100)
void Concat()
{
	strToken += ch;
}

void Retract()
{
	fp--;
	ch = codefile[fp];
}

void Analysis()
{
	strToken = "";
	GetChar();
	GetBC();
	if (IsLetter())
	{
		while (IsLetter() || IsDigit())
		{
			Concat();
			GetChar();
		}
		Retract();
	}
	else if (IsDigit())
	{
		while (IsDigit())
		{
			Concat();
			GetChar();
		}
		Retract();
	}
	else if (ch == ':')
	{
		Concat();
		GetChar();
		if (ch == '=')
			Concat();
		else
			Retract();
	}
	else if (ch == ';')
		Concat();
	else if (ch == ',')
		Concat();
	else if (ch == '=')
		Concat();
	else if (ch == '<>')
		Concat();
	else if (ch == '<')
		Concat();
	else if (ch == '<=')
		Concat();
	else if (ch == '>')
		Concat();
	else if (ch == '>=')
		Concat();
	else if (ch == '+')
		Concat();
	else if (ch == '-')
		Concat();
	else if (ch == '*')
		Concat();
	else if (ch == '/')
		Concat();
	else if (ch == '(')
		Concat();
	else if (ch == ')')
		Concat();
	else if (ch == '\n')
	{
		line++;
		Concat();
	}
}


void GetWordArray()
{
	ReadFile();
	while (codefile[fp])
	{
		if (wp >= WAlen)
		{
			string *temp = new string[WAlen];
			for (int i = 0; i < WAlen; i++)
				temp[i] = WordArray[i];
			delete[]WordArray;
			WordArray = new string[WAlen + WordNum];
			for (int i = 0; i < WAlen; i++)
				WordArray[i] = temp[i];
			delete[]temp;
			WAlen += WordNum;
		}
		Analysis();
		if (IsUseStrToken())
		{
			lines[wp] = line;
			WordArray[wp++] = strToken;
		}
	}
	WAlen = wp;
	wp = 0;
}

void Ana_statement()
{
	void Ana_body();
	if (IsId() || WordArray[wp] == ":=")
	{
		if (WordArray[wp] == ":=")
			cout << lines[wp - 1] << ":  " << "第" << wp + 1 << "个词处发生了statement语法错误: 缺少id" << endl;
		else
			wp++;
		if (WordArray[wp] == ":=")
		{
			wp++;
			Ana_exp();
		}
		else {
			cout << lines[wp - 1] << ":  " << "第" << wp + 1 << "个词处发生了statement语法错误: 缺少“:=”" << endl;
			Ana_exp();
		}
	}
	else if (WordArray[wp] == "if")
	{
		wp++;
		Ana_lexp();
		if (WordArray[wp] == "then")
		{
			wp++;
			Ana_statement();
			if (WordArray[wp] == "else")
			{
				wp++;
				Ana_statement();
			}
		}
		else {
			cout << lines[wp - 1] << ":  " << "第" << wp + 1 << "个词处发生了statement语法错误: 缺少关键字“then”" << endl;
			Ana_statement();
			if (WordArray[wp] == "else")
			{
				wp++;
				Ana_statement();
			}
		}
	}
	else if (WordArray[wp] == "while")
	{
		wp++;
		Ana_lexp();
		if (WordArray[wp] == "do")
			wp++;
		else {
			cout << lines[wp - 1] << ":  " << "第" << wp + 1 << "个词处发生了statement语法错误: 缺少关键字“do”" << endl;
		}
		Ana_statement();
	}
	else if (WordArray[wp] == "call")
	{
		wp++;
		if (IsId())
			wp++;
		else {
			cout << lines[wp - 1] << ":  " << "第" << wp + 1 << "个词处发生了statement语法错误: 缺少id" << endl;
		}
		if (WordArray[wp] == "(")
			wp++;
		else {
			cout << lines[wp - 1] << ":  " << "第" << wp + 1 << "个词处发生了statement语法错误: 缺少“(”" << endl;
		}
		if ((WordArray[wp] == "+") || (WordArray[wp] == "-") || (WordArray[wp] == "(") || IsId() || IsInteger())
		{
			Ana_exp();
			while (WordArray[wp] == ",")
			{
				wp++;
				Ana_exp();
			}
		}
		if (WordArray[wp] == ")")
			wp++;
		else {
			cout << lines[wp - 1] << ":  " << "第" << wp + 1 << "个词处发生了statement语法错误: 缺少“)”" << endl;

		}
	}
	else if (WordArray[wp] == "begin")
		Ana_body();
	else if (WordArray[wp] == "read")
	{
		wp++;
		if (WordArray[wp] == "(")
			wp++;
		else {
			cout << lines[wp - 1] << ":  " << "第" << wp + 1 << "个词处发生了statement语法错误: 缺少“(”" << endl;
		}
		if (IsId())
			wp++;
		else {
			cout << lines[wp - 1] << ":  " << "第" << wp + 1 << "个词处发生了statement语法错误: 缺少id" << endl;
		}
		while (WordArray[wp] == ",")
		{
			wp++;
			if (IsId())
				wp++;
			else {
				cout << lines[wp - 1] << ":  " << "第" << wp + 1 << "个词处发生了statement语法错误: 缺少id" << endl;
			}
		}
		if (WordArray[wp] == ")")
			wp++;
		else {
			cout << lines[wp - 1] << ":  " << "第" << wp + 1 << "个词处发生了statement语法错误: 缺少“)”" << endl;
		}
	}
	else if (WordArray[wp] == "write")
	{
		wp++;
		if (WordArray[wp] == "(")
			wp++;
		else {
			cout << lines[wp - 1] << ":  " << "第" << wp + 1 << "个词处发生了statement语法错误: 缺少“(”" << endl;
		}
		Ana_exp();
		while (WordArray[wp] == ",")
		{
			wp++;
			Ana_exp();
		}
		if (WordArray[wp] == ")")
			wp++;
		else {
			cout << lines[wp - 1] << ":  " << "第" << wp + 1 << "个词处发生了statement语法错误: 缺少“)”" << endl;
		}
	}
	else {
		cout << lines[wp - 1] << ":  " << "第" << wp + 1 << "个词处发生了statement语法错误: 未找到开始符号" << endl;

	}
}

 当时没养成写注释的好习惯,如果有什么问题就在下面问吧,不保证还记得


 四、测试截图

program ;
const m:=24 ,:=81;
var x,y,z,q,r
procedure multiply(x,y;
    var a,b;
    begin
       a:=x; b:=y; z;
        while b>0 
            begin
                if odd b  z:=z+a;
                    a:=2*b*c; b:=b/2
            end
    end
    x:=m y:=n;
    call multiply);
    write(a+b-1,d*c*b*a);
    read (a,b

以上为测试代码,语言Pascal

以下为运行结果,格式为  “行:    第n个词处发生了XXX语法错误,错误原因”

 

 

 

 

编译原理实验一:简单PL/0词法分析器C语言代码
Chen_dSir的博客
04-18 1万+
思路分析:我的个人思路比较简单,首先定义几个二维数组,分别保存PL语言关键字,界符,或者运算符,然后在主函数中,读入字符串,或者从文件中读入,然后对字符串进行分割,进行一些过滤空格(ASCII码为10,换行的ASCII码为13),之后将分割后的字符串与我们定义的数组进行比较(这相当于一个词库),假如匹配,就与之对应对它进行标记,如果既不是关键字,也不是界符.运算符,那么就是用户自定义的标识符.然后
简单的PL/0词法分析
最新发布
m0_62437398的博客
06-25 369
如果识别的首个数字是0,则判断它下一个字符是否是字母,若是,则报错,否则输出0;识别数字时,要区分0和其它数字。0不能做其他数字的开头。其它的数字和NUM转态一致。可将NUM这个状态拆分。
Pascal语法分析器
06-20
Pascal语法分析器 编译原理实验
pascal语法分析
11-02
简单的语法分析程序,仅供参考,有缘人自行下载,有问题可在评论区留言,看到会回复,欢迎交流。 代码说明(CodeBlocks16可直接运行): 1. Pascal语言不区分大小写,故需要强制转换。 2. 主要为if/then/else,begin/end的语义分析,但框架已搭建好,可稍作修改适应其他语言的语义分析。
pascal语言词法分析
01-05
东华大学 姚砺 pascal语言词法分析器,全部实现
基于Pascal语言语法分析器
12-13
包含编译原理实验中的语法分析源程序及实验报告,此语法分析器基于pascal语言,在实验报告中有详细的说明,该语法分析器只能说是小语言语法分析器,文法并不齐全,供大家参考
基于Python实现的类Pascal语言词法分析语法分析器
毕业作品网站
09-11 548
使用Python实现的类Pascal语言词法分析语法分析器
bianyiqi.rar_Pascal汇编器_汇编器Pascal
09-23
通过实现这样的工具,可以深入理解编译器的工作流程,掌握词法分析器、语法分析器的设计,以及如何将高级语言的抽象概念映射到底层的机器指令。同时,这也是一种对Pascal语言特性的深度学习,因为开发者需要理解...
计算机软件-商业源码-简易文件分割器(纯PASCAL编写).zip
05-23
【标题】中的“计算机软件-商业源码-简易文件分割器(纯PASCAL编写).zip”表明这是一个基于PASCAL编程语言开发的商业源码,主要用于实现文件分割功能。文件分割器是一种实用工具,它将大文件拆分为较小的部分,以便于...
C语言实现简易词法分析
这些标记随后会被语法分析器用于构建抽象语法树(AST),进一步解析程序的结构和含义。 总结来说,这个简易词法分析程序是用C语言实现的一个基础编译器组件,它的任务是解析Pascal语言的源代码,提取出关键字、...
Pascal语义分析器
06-12
紧接我之前提交的Pascal词法和语法分析器,这里是实现了赋值、if-语句、for-语句Pascal语法制导的翻译的语义分析器。
pascal语言词法分析程序
12-09
能识别基本pascal语言,输入二元式,很好很强大,下下就知道了
Delphi做的用于分析Pascal语言词法分析
11-14
编译原理词法分析器,上学时做的,当时花了我许多功夫,现在看来做的还是很不错的。
Pascal语法检测
10-21
对给定一个Pascal源文件,检查其中 (1)begin与end (2)if,then,else 是否合法配对。 对于begin与end,可以理解为C语言中的“{”与“}” 对于if,then,else,可以这么理解:if与then合在一起相当于C语言中的if, else与C语言中的else完全相同。 ((Given a Pascal source file, to check which (1) begin and end (2) if, then, else the legality of pairing. For begin and end, can be understood as the C language " {" and " }" if, then, else, so to understand: if and then together the equivalent of if, else in the C language and C language else exactly the same.))
编译原理上机作业-词法分析程序实现PASCAL简单词法分析器)
06-02
压缩文档里包括源代码和PASCAL词法分析器的设计要求等。
Delphi自制简易Sql查询分析器..rar
04-27
在本项目中,我们关注的是一个使用Delphi开发的简易SQL查询分析器。Delphi是一款强大的Windows应用程序开发工具,以其高效的编译器和面向对象的Pascal编程语言(Object Pascal)而闻名。这个分析器可能是为了帮助...
用Lex编写的简易版C语言词法分析器(编译原理大作业1)
热门推荐
never_say_never7的博客
11-16 1万+
本文讲解关于如何用lex工具来编写一个简易版的C语言词法分析器。
编译原理之C++&&Python进行Pascal词法分析&&语法分析
aaaadioppa的博客
10-20 2706
这编译原理的课设真烦呀,不过总算写完了。下面的我和室友写的代码(其实还有Bug,但过老师的检验还是够了),供大家去学习。主要去学习这个思想——嵌套与递归。 代码C++部分是我Liu Yudi写的,Python是室友Qu Ao和Che Pengyuan写的。 下面是PL/0语言的描述: PL/0语言的BNF描述(扩充的巴克斯范式表示法) <prog> → program <id>;<block> <block> → [<condecl>][<v
Pascal语言词法分析实验(简易版)
Cheney ' blog
04-05 2819
一、 实验目的 设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。 二、 实验要求 2.1 待分析的简单的词法 (1)关键字: begin if then while do end 所有的关键字都是小写。 (2)运算符和界符 : = + - * / < <= <> > >= = ; ( ) # (3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义: ID = letter (letter | dig
写文章

热门文章

  • 无序表删除重复元素 2909
  • Pascal 语法分析器 简易实现 1529
  • Pascal 词法分析器 简易实现 1223
  • gcc编译 435
  • c++学习记录1 类的多文件操作时的一个小问题(已解决) 300

分类专栏

  • 随笔记录 1篇
  • 算法练习 1篇
  • 编译原理 2篇
  • c++ 4篇

最新评论

  • 无序表删除重复元素

    Mr.Poem: 会,本质是空间换时间,很简单的一个思想罢了

  • 无序表删除重复元素

    Zuo蓝: 原数组输入超过50的数为什么不会越界?

  • 无序表删除重复元素

    Zuo蓝: 原数组输入超过50的数为什么不会越界?

  • 无序表删除重复元素

    qq_58936835: 大佬牛逼

  • Pascal 语法分析器 简易实现

    Mr.Poem: 没有这么多,好像就500行左右吧,子函数可以嵌套调用,某些表达式不考虑健壮性的话几乎三四行就搞定了。

最新文章

  • java实现简易RPC框架
  • gcc编译
  • vim操作
2023年1篇
2021年5篇
2020年1篇
2019年2篇

目录

目录

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值

玻璃钢生产厂家泉州玻璃钢仿真水果雕塑定制江西玻璃钢彩绘雕塑郊区玻璃钢花盆花器牡丹江校园玻璃钢雕塑厂家不锈钢和玻璃钢雕塑西藏公园玻璃钢雕塑生产厂家宜兴商场主题美陈公园摆件玻璃钢雕塑供应商个性化玻璃钢雕塑公司方案赤坎玻璃钢雕塑厂家墙面玻璃钢雕塑四川玻璃钢造型雕塑宁波玻璃钢雕塑诚信企业鹰潭户内玻璃钢雕塑哪家便宜深圳坂田玻璃钢花盆西湖区玻璃钢雕塑介绍辽宁商场创意商业美陈定制福建主题商场美陈销售厂家定西户外玻璃钢雕塑制作玻璃钢卡通雕塑费用天津公园主题玻璃钢卡通雕塑费用玻璃钢大白菜雕塑报价双十一商场美陈方案陕西玻璃钢酒店人物雕塑资阳玻璃钢卡通雕塑鹤壁玻璃钢卡通雕塑价格报价呼和浩特玻璃钢卡通雕塑广西雕塑玻璃钢雕塑定制上海商场节日活动美陈布置彩虹线商场美陈香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化