编译原理课程设计 算符优先算法 Java版

编译原理课程设计 算符优先算法 Java版

一、 设计目的及设计要求

原题目设计内容及要求: 实现教材 P.92 优先表构造算法。对任一给定的算符优 先文法 G,假定所有非终结符 P 的 FIRSTVT§、LASTVT§均已知。以教材 P.90 例 5.4 文法为例,程序生成表 5.1 优先表。

二、 开发环境描述

64****位window11

开发语言:Java

版本:Java8

开发工具:IDEA集成开发环境

三、设计内容、主要算法描述

设计内容包括问题的描述及解决的方法

算法部分:在原有题目要求的基础上,我实现了FIRSTVT和LASTVT的自动构造算法,然后根据它们构造算符优先表table,最后我还完成了对一个输入串进行算符优先分析,并显示结果。所有的算法都是我参考课本独立完成的。在实验过程中,我刚开始是按照实验要求根据已有的FIRSTVT和LASTVT构造优先表,在完成基本的功能后,我开始对实验进行优化和扩充。首先,我编写了FIRSTVT的构造算法,完成后,我又根据FIRSTVT迅速构造出LASTVT,因为他们两个的构造算法相似。接着我开始测试代码正确输出优先表后,我开始着手构造分析程序。通过编写由table表构造的分析程序后,我又在控制台进行输入输出测试。完成分析程序的构造后,我开始进一步完善程序,为了达到对任何算符优先文法都能在这个程序中进行构造分析,我编写了初始化方法,在初始化程序中读取输入的文法,构造相关的终结符集vt,非终结符集vn,产生式,还有开始符号等。最后算法部分基本上实现了一个算符优先分析的全部功能,功能上基本完善。

GUI界面部分:主要使用swing包做界面,awt包做事件监听。主要是显示文本框,表格,给按钮绑定事件。在此我实现了两个监听器,一个用来监听按钮点击,进行文本框输入数据读取和调用算法分析并展示结果,另外为了方便用户使用,我还添加了两个按钮,一个点击后可以填充默认文法,一个点击后可以清空文本框数据。另一个监听器主要是实现文本框焦点提示信息。

具体界面显示如下:

在这里插入图片描述

遇到的主要问题:

算法方面主要是如何合理设计数据的存储以及读取,我这里采用HashSet和HashMap进行vn,vt,以及产生式的存储,采用char类型的数组存储优先级。在构造FISTVT和LASTVT时用两个栈同步完成非终结符对应一个终结符,即在栈中相同位置处的非终结符的firstVt包含该终结符。在构造分析算法时,将每个步骤存储到自己定义的一个ArrayList中。界面方面主要是如何将数据展示到Frame上,我这里用swing包下的table模型。然后就是如何优化界面,为了方便用户使用和体验,我用事件监听做了相关的优化,还有就是在输入文法不是算符优先文法时,也会弹窗警告框。

算法方面就是当点击分析按钮时,依次执行下面几个方法:

Priority.init();//初始化
Priority.getFirstVt();//构建FIRSTVT
Priority.getLastVt();/构建LASTVT
Priority.creatTable();//构建优先表
Priority.analyze();//分析输入串

四、设计的输入和输出形式

输入输出内容、格式的描述:

因为自己是在题目原有的基础上扩充的,原题目只要求根据已有的FIRSTVT和LASTVT构造优先表,而我的程序功能是根据输入的算符优先文法,自动生成FIRSTVT和LASTVT,然后再自动构造优先表,并且可以输入符号串进行算符优先分析,并显示分析过程。

算法优先文法输入形式是通过GUI界面,在文本输入框内进行输入。GUI界面有两个文本输入框分别用来输入算符优先文法和要分析的符号串。输入格式是每个产生式之间用 # 隔开,而要分析的符号串的输入形式是符号串要以 # 结尾。

程序输出有两种形式,可以直接在控制台打印相关结果,也可以显示到GUI界面中,以表格的形式展现。程序输出结果包括FIRSTVT,LASTVT,算符优先表table,输入串的分析过程(包括步骤,符号栈,剩余输入串,动作),所以输出都是自动生成。

五、结果和代码

以下就是测试输入文法E->E+T|T#T->T*F|F#F->(E)|i和待分析串i+i# 所生成的FIRSTVT,LASTVT ,table,分析过程

在这里插入图片描述
在这里插入图片描述

如果输入不是算符优先文法会提示错误,并终止分析,这时再改成正确文法,点击按钮依然可以继续分析。效果如下:
在这里插入图片描述
有用的话,请不要吝啬,动动小手点个赞把~

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
算符优先分析法是一种自下而上的语法分析方法,它可以用于分析和处理算术表达式、布尔表达式等。下面是算符优先分析法实现步骤: 1. 定义终结符和非终结符:终结符是指不能再分解的基本符号,如数字、运算符等;非终结符是指可以分解成其他符号的符号,如表达式、语句等。 2. 定义运算符之间的优先关系和结合性质:将运算符按照优先级从高到低排列,相同优先级的运算符再按照结合性质(左结合或右结合)进行排列。 3. 构造算符优先关系表:根据定义的运算符优先关系和结合性质,构造算符优先关系表。表中的行和列分别表示两个相邻的运算符,表中的元素表示它们之间的优先关系(“<”表示优先级低,“>”表示优先级高,“=”表示优先级相等)。 4. 进行语法分析:将输入的表达式转换成一个个终结符和非终结符的序列,然后根据算符优先关系表进行分析。具体地,从左到右扫描输入序列,将扫描到的符号压入栈中,同时比较栈顶符号和下一个输入符号之间的优先关系,如果栈顶符号的优先级低于或等于下一个输入符号的优先级,则将下一个输入符号压入栈中;否则,从栈中弹出一个或多个符号进行归约,直到栈顶符号的优先级低于或等于下一个输入符号的优先级。 5. 进行表达式求值:在进行归约时,如果遇到两个相邻的终结符之间有一个运算符,则可以对它们进行求值,并将结果压入栈中。最终,栈中只剩下一个值,即为表达式的值。 下面是一个简单的算符优先分析法实现例子,用于分析和处理四则运算表达式: ```python # 定义终结符和非终结符 terminals = ['+', '-', '*', '/', '(', ')', 'num'] non_terminals = ['E', 'T', 'F'] # 定义运算符之间的优先关系和结合性质 precedence = { '+': {'+': '>', '-': '>', '*': '<', '/': '<', '(': '<', ')': '>', 'num': '<'}, '-': {'+': '>', '-': '>', '*': '<', '/': '<', '(': '<', ')': '>', 'num': '<'}, '*': {'+': '>', '-': '>', '*': '>', '/': '>', '(': '<', ')': '>', 'num': '<'}, '/': {'+': '>', '-': '>', '*': '>', '/': '>', '(': '<', ')': '>', 'num': '<'}, '(': {'+': '<', '-': '<', '*': '<', '/': '<', '(': '<', ')': '=', 'num': '<'}, ')': {'+': '>', '-': '>', '*': '>', '/': '>', '(': ' ', ')': '>', 'num': ' '}, 'num': {'+': '>', '-': '>', '*': '>', '/': '>', '(': ' ', ')': '>', 'num': ' '} } # 构造算符优先关系表 table = {} for i in range(len(terminals)): table[terminals[i]] = {} for j in range(len(terminals)): table[terminals[i]][terminals[j]] = precedence[terminals[i]][terminals[j]] # 进行语法分析 def parse(expr): stack = ['#'] tokens = expr.split() for token in tokens: while table[stack[-1]][token] == '>': op = stack.pop() if op in ['+', '-', '*', '/']: b = stack.pop() a = stack.pop() stack.append(str(eval(a + op + b))) else: stack.pop() if table[stack[-1]][token] == '<' or table[stack[-1]][token] == '=': stack.append(token) else: raise ValueError('Invalid expression') while stack[-1] != '#': op = stack.pop() if op in ['+', '-', '*', '/']: b = stack.pop() a = stack.pop() stack.append(str(eval(a + op + b))) else: raise ValueError('Invalid expression') return stack[0] # 进行表达式求值 expr = '3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3' result = parse(expr) print(result) # 输出:3.0001220703125 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦中情几许

感谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值