编译原理课程设计:语法分析器

本文档介绍了如何使用Python实现一个LR(1)语法分析器,包括项目集族构造、action和goto表生成,以及如何进行语法分析。在PyCharm环境下进行开发,程序读取2º型文法和词法分析结果,输出符合文法与否的判断及错误信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

配套代码:

编译原理课程设计:语法分析器-Python文档类资源-优快云下载所使用的开发环境:Windows10、python(PyCharm)环境注意:expression更多下载资源、学习资料请访问优快云下载频道.https://download.youkuaiyun.com/download/RLIRiong/85393593?spm=1001.2014.3001.5503

github:

https://github.com/Afaliya0-0Liong/Parser-https://github.com/Afaliya0-0Liong/Parser-

要求:

创建一个使用LR(1) 方法的语法分析程序,程序有两个输入:1)一个是文本文档,其中包含2º型文法(上下文无关文法)的产生式集合;2)任务1词法分析程序输出的(生成的)token令牌表。程序的输出包括:YES或NO(源代码字符串符合此2º型文法,或者源代码字符串不符合此2º型文法);错误提示文件,如果有语法错标示出错行号,并给出大致的出错原因。

开发环境:

Windows10、python(PyCharm)环境。

项目简介:

程序读入上下文无关文法,并进行拓广文法,将产生式依次形成项目进行储存,设定好起点进行处理得到完整的项目集族,按照项目集族之间的转换得到action、goto表,读取词法分析得到的token(详情看我的词法分析器,也可以按照我的格式进行自创,格式:(行数, token分类, token内容)),按照之前得到的action、goto表进行处理,得到语法分析的结果,查看是否符合自己设定的语法,如果出错可以形成缺失者错误导致的错误报告,并输出到result.txt(正确会得到‘YES’)。

相关数据结构:

   该语法分析器主要依赖LR1类,通过内部的project_family保存项目集族,links等数据结构共同使用进行项目集族的跳转。

关于dict字典,引用了defaultdict类带替代部分字典类,优势在于如果键值不存在不会引发keyerror。

class LR1:

数据结构名

类型

介绍

symbol

列表

保存除了’#’以外的所有终结符。

project_family_num

int

保存总共的项目集族数。

project_num

int

保存总共的项目数。

next_states

defaultdict

[id][进位符号]=下一个项目集族。

projects

defaultdict

记录所有项目及编号,例如projects[S'][·S] = 1。

links

defaultdict

用于项目集族的转换连接,例如:

links[当前项目集族编号][下一个项目集族编号] = 转换需要的进位符。

first

defaultdict

保存所有非终结符的first集。

search

defaultdict

保存前向搜索符。

project_index

字典

根据编号查找项目,例如:project_index[1] = (S', ·S) 。

project_family

字典

表示项目集族。

production

列表

表示产生式,从1开始保存方便后续使用。

production_index

defaultdict

通过编号来索引产生式。

states: 集合类,保存项目集族编号。

states

集合

保存项目集族编号。

start_state

int

表示起点的项目集族编号。

详细设计:

构造项目集族的方法:

函数名

返回值

方法介绍

go_LR1(alphabet, list_source)

LR1对象。

list_source表示所有的产生式,以二维列表格式传入,该方法读取二型文法并添加项目,添加first集,返回包含整个DFA的LR1对象。

go_dfa(lr1)

没有返回值。

该方法在go_LR1内部,目的是形成DFA,内容保存在LR1对象中。

get_first_ahead(self, big_sign)

返回终结符。

该方法扫描计算big_sign的first集,保存到first中。

add_search(self, state_num, project, sign)

没有返回值。

将sign添加到state_num下项目project的前向搜索符中。

add_first(self, big_sign, sign)

没有返回值。

将sign添加到big_sign的first集中。

get_first(self, big_sign)

返回first集内容。

用于构造过程中需要first集时的寻找,如果有新增则会调用上面方法添加到first集。

get_project_family(self, project_family, state_num)

返回项目集族。

遍历项目得到·S这类指向非终结符的项目来寻找S开头且·在最开始的项目,得到一个完整的项目集族。

be_the_only(self, project_family)

返回项目集族。

去重复,合并只有搜索符不同其他相同的项目。

get_closure_search(self, left, state_num, sign)

返回项目集族。

用于补全项目集族。

get_closure(self, big_sign)

返回项目集族。

用于补全项目集族,上下方法略有不同。

get_tmp_family(self, tmp_family)

返回项目集族。

得到类似上面的get_project_family,得到tmp的闭包从而得到完整的项目集族。

link(self, sta, next_sta, carry)

没有返回值。

进行项目集族之间的连接。

get_next_sta(self, sta, carry)

返回项目编号以及是否建立新状态的布尔值。

carry表示进位的符,如果存在下一个项目集族的编号就返回编号,否则新建一个项目集族。

add_project_family(self, next_sta, tmp_family)

没有返回值。

将项目添加到项目集族中,从temporary转正到正式的项目集族。

extend(list_source)

返回拓广文法之后的产生式。

拓广文法。

构造actiongoto表的方法:

函数名

返回值

方法介绍

go_LR1_table(lr1)

成功则返回action, goto, True。失败返回三个False。

形成action、goto表,返回action、goto表以及一个布尔值表示是否成功,如果创建失败返回三个False,用最后一个布尔值来判断是否要进行语法分析。

add_action(sta, sign, state, action)

没有返回值。

将转换添加到action表中。

go_jump(lr1, sta, sign)

指定的下一个项目集族编号。

用于项目集族的编号跳转。

add_goto(sta, carry, go, goto)

没有返回值。

将转换添加到goto表中。

语法分析的方法:

函数名

返回值

方法介绍

get_code()

两个列表,一个储存扫描的词,一个对照词储存行数

用于读取上一个任务得到的经过扫描的token表,并记录行数,方便语法分析的处理。

analyse(action, goto, lr1)

返回类型不固定:

  • 成功,返回一个str类型和两个True
  • 正常错误,返回一个错误信息列表,一个False和int类型错误行数
  • 缺失导致的错误,返回两个False和一个int类型错误函数

语法分析的核心函数,将上述方法得到的token处理后依据前面得到的action、goto表进行语法分析,出错可以大致写出错误信息。

read(action, goto, lr1)

没有返回值。

语法分析的总函数,在这里调用analyse,成功输出”YES”,反之输出”NO”以及错误信息。

main函数流程:

测试与运行:

首先获取任务一的token,如图:

 运行程序,得到结果:

 修改token,在末尾多加几行:

 运行程序得到结果:

 这里的错误行信息表示第九行的限定符后面不可以接第十行的限定符。

现在进行删除测试,如图:

运行结果:

 运行完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值