郑州大学编译原理实验三算符优先分析算法JAVA
admin
2024-01-20 03:21:57
0

一、 实验目的

根据算符优先分析法,对表达式进行语法分析,使其能够判断一个表达式是否正确。通过算符优先分析方法的实现,加深对自下而上语法分析方法的理解。

二、 实验内容

1、输入文法。可以是如下算术表达式的文法(你可以根据需要适当改变):
E→E+T|E-T|T
T→T*F|T/F|F
F→(E)|i

2、对给定表达式进行分析,输出表达式正确与否的判断。
程序输入/输出示例:
输入:1+2;
输出:正确
输入:(1+2)/3+4-(5+6/7);
输出:正确
输入:((1-2)/3+4
输出:错误
输入:1+2-3+(*4/5)
输出:错误

3、参考数据结构
char *VN=0,*VT=0;//非终结符和终结符数组
char firstvt[N][N],lastvt[N][N],table[N][N];
typedef struct //符号对(P,a)
{
char Vn;
char Vt;
} VN_VT;
typedef struct //栈
{
VN_VT *top;
VN_VT *bollow;
int size;
}stack;

4、根据文法求FIRSTVT集和LASTVT集

5、构造算符优先分析表

6、构造总控程序

7、对给定的表达式,给出准确与否的分析过程
8、给出表达式的计算结果。(本步骤可选作)

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.*;/*** @author [25'h]* @datetime 2022.11.02*/
public class Reducing {public static String startLabel;//开始符public static ArrayList terSymbol = new ArrayList<>();// 终结符public static ArrayList non_ter = new ArrayList<>();// 非终结符public static HashMap> formula = new HashMap<>();//产生式public static HashMap[]> firstvtAndLastvt = new HashMap<>();//FIRST  和  FOLLOW/*firstvtAndLastvt的数据含义:- key : 非终结符- value : 非终结符对应的FIRSTVT  和  FOLLOWVT 集- 1     非终结符对应的FIRSTVT- 2     非终结符对应的FOLLOWVT*/public static boolean[] booleansFirst;// 辅助变量public static boolean[] booleansLast;public static String[][] table;//优先表public static String objString;// 目标匹配字符串public static LinkedList deque;public static void main(String[] args) {File file = new File("src/StringToJAVA/test3.txt");BufferedReader bufferedReader;try {// 读取文法和目标式子bufferedReader = new BufferedReader(new FileReader(file));startLabel = bufferedReader.readLine();// 读取非终结符non_ter.addAll(Arrays.asList(bufferedReader.readLine().split(" ")));booleansFirst = new boolean[non_ter.size()];// 初始化辅助变量booleansLast = new boolean[non_ter.size()];// 初始化firstAndFollow中的Map对象for (String s : non_ter) {firstvtAndLastvt.put(s, new HashSet[]{new HashSet(), new HashSet()});}// 读取终结符terSymbol.addAll(Arrays.asList(bufferedReader.readLine().split(" ")));table = new String[terSymbol.size() + 1][terSymbol.size() + 1];//将产生式右部或表达式分离String s;while ((s = bufferedReader.readLine()).contains("->")) {String[] split = s.split("->");formula.put(split[0], Arrays.asList(split[1].split("\\|")));}// 赋值目标串objString = s;} catch (Exception e) {e.printStackTrace();}// 生成firstvt和lastvtgenerateFirstVTAndLastVT();// 生成优先分析表generateTable();// 归约reducing();show();}private static void reducing() {// 终结符中添加结尾符号terSymbol.add("#");deque = new LinkedList<>();deque.push("#");for (int i = 0; i < objString.length(); i++) {// 取出下一个字符String sub = objString.substring(i, i + 1);if (terSymbol.contains(sub)) {// 是终结符// 栈最上面的终结符是tempString temp = terSymbol.contains(deque.peek()) ? deque.peek() : deque.get(1);// 看看跟上一个终结符和sub大优先级关系String bol = table[terSymbol.indexOf(temp)][terSymbol.indexOf(sub)];// 是> 就归约if (bol.equals(">")) {func(sub);}// 归约后终结符入栈}deque.push(sub);// 直接压入showCurStack(i);}}//输出当前的栈状态private static void showCurStack(int i) {StringBuffer b = new StringBuffer();for (int j = deque.size() - 1; j >= 0; j--) {b = b.append(deque.get(j));}if (i != objString.length() - 1)b = b.append("\t\t\t").append(objString.substring(i + 1));System.out.println(b.toString());}private static void func(String curTer) {String te;// 栈顶非终结符读出if (!terSymbol.contains(deque.peek())) {deque.pop();}do {te = deque.pop();// 当前规约串的终结符te
// te左的非终结符if (!terSymbol.contains(deque.peek())) {deque.pop();}} while (!table[terSymbol.indexOf(deque.peek())][terSymbol.indexOf(te)].equals("<"));// 栈顶终结符te = deque.peek();deque.push("N");// 标记// 若还是>,则递归调用if (table[terSymbol.indexOf(te)][terSymbol.indexOf(curTer)].equals(">")) {func(curTer);}}private static void generateTable() {// 对于每个公式都要取出终结符for (String non : formula.keySet()) {List list = formula.get(non);//non这个非终结符对应的生成式for (String f : list) {// 对于每个式子fArrayList li = new ArrayList<>();// 每个式子的终结符记下来,因为他们之间的关系是=// 对式子f要查找终结符位置for (int i = 0; i < f.length(); i++) {// 对于f中每个元素subString sub = f.substring(i, i + 1);// 若是终结符if (terSymbol.contains(sub)) {li.add(sub);//几下终结符// 左边有非终结符if (i != 0 && non_ter.contains(f.substring(i - 1, i))) {//赋值“>”pre(f.substring(i - 1, i), sub);}//右边有非终结符if (i != f.length() - 1 && non_ter.contains(f.substring(i + 1, i + 2))) {//赋值“<”post(f.substring(i + 1, i + 2), sub);}}}// 想等情况赋值,注意是 j = i + 1for (int i = 0; i < li.size(); i++) {for (int j = i + 1; j < li.size(); j++) {table[terSymbol.indexOf(li.get(i))][terSymbol.indexOf(li.get(j))] = "=";}}}}// 关于#的赋值Set[] sets = firstvtAndLastvt.get(startLabel);for (String s : sets[0]) {table[terSymbol.size()][terSymbol.indexOf(s)] = "<";}for (String s : sets[1]) {table[terSymbol.indexOf(s)][terSymbol.size()] = ">";}table[terSymbol.size()][terSymbol.size()] = "=";}private static void post(String non, String ter) {int index = terSymbol.indexOf(ter);Set set = firstvtAndLastvt.get(non)[0];for (String s : set) {table[index][terSymbol.indexOf(s)] = "<";}}private static void pre(String non, String ter) {int index = terSymbol.indexOf(ter);Set set = firstvtAndLastvt.get(non)[1];for (String s : set) {table[terSymbol.indexOf(s)][index] = ">";}}//生成firstvt和lastvtprivate static void generateFirstVTAndLastVT() {for (String s : non_ter) {if (!booleansFirst[non_ter.indexOf(s)])generateEachFirstVT(s);if (!booleansLast[non_ter.indexOf(s)]) {generateEachLastVT(s);}}}/*生成每个非终结符non的Lastvt集*/private static void generateEachLastVT(String non) {Set curList = firstvtAndLastvt.get(non)[1];for (String s : formula.get(non)) {// lastvt本质就是firstvt反过来的求法modify(non, curList, new StringBuffer(s).reverse().toString(), 1);}booleansLast[non_ter.indexOf(non)] = true;}/*生成每个非终结符non的Firstvt集*/private static void generateEachFirstVT(String terNon) {Set curList = firstvtAndLastvt.get(terNon)[0];for (String s : formula.get(terNon)) {modify(terNon, curList, s, 0);}booleansFirst[non_ter.indexOf(terNon)] = true;}private static void modify(String non, Set curList, String s, int i) {String firstSub = s.substring(0, 1);if (terSymbol.contains(firstSub)) {// 终结符开头curList.add(firstSub);} else {// 非终结符开头// 终结符是第二个位置if (s.length() >= 2 && terSymbol.contains(s.substring(1, 2))) {curList.add(s.substring(1, 2));}// firstSub和non相同,避免栈溢出返回if (firstSub.equals(non)) return;if (i == 0) {// 求firstvt,用booleansFirstif (!booleansFirst[non_ter.indexOf(firstSub)]) {generateEachFirstVT(firstSub);}} else {// 求lastvt,booleansLastif (!booleansLast[non_ter.indexOf(firstSub)]) {generateEachLastVT(firstSub);}}curList.addAll(firstvtAndLastvt.get(firstSub)[i]);}}private static void show() {System.out.println(startLabel);System.out.println(Arrays.toString(non_ter.toArray()));System.out.println(Arrays.toString(terSymbol.toArray()));for (String s : formula.keySet()) {System.out.println(s + "\t" + Arrays.toString(formula.get(s).toArray()));}System.out.println();for (String s : firstvtAndLastvt.keySet()) {System.out.println(s + "\t" + Arrays.toString(firstvtAndLastvt.get(s)[0].toArray()) + "\t" + Arrays.toString(firstvtAndLastvt.get(s)[1].toArray()));}System.out.println();for (String[] strings : table) {System.out.println(Arrays.toString(strings));}}}

test3.txt文件:

E
E T F
i * / + - ( )
E->E+T|E-T|T
T->T*F|T/F|F
F->(E)|i
(1+2)/3+4-(5+6/7)#

输出结果:

"D:\Program Files\Java\jdk1.8.0_291\bin\java.exe" "-javaagent:D:\IntelliJ IDEA 2020.1\lib\idea_rt.jar=54769:D:\IntelliJ IDEA 2020.1\bin" -Dfile.encoding=UTF-8 -classpath "D:\Program Files\Java\jdk1.8.0_291\jre\lib\charsets.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\deploy.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\access-bridge-64.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\cldrdata.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\dnsns.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\jaccess.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\jfxrt.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\localedata.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\nashorn.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunec.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunjce_provider.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunmscapi.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunpkcs11.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\zipfs.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\javaws.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\jce.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\jfr.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\jfxswt.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\jsse.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\management-agent.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\plugin.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\resources.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\rt.jar;D:\code_management\algorithm\out\production\algorithm" StringToJAVA.Reducing
#(			1+2)/3+4-(5+6/7)#
#(1			+2)/3+4-(5+6/7)#
#(1+			2)/3+4-(5+6/7)#
#(1+2			)/3+4-(5+6/7)#
#(N)			/3+4-(5+6/7)#
#N/			3+4-(5+6/7)#
#N/3			+4-(5+6/7)#
#N+			4-(5+6/7)#
#N+4			-(5+6/7)#
#N-			(5+6/7)#
#N-(			5+6/7)#
#N-(5			+6/7)#
#N-(5+			6/7)#
#N-(5+6			/7)#
#N-(5+6/			7)#
#N-(5+6/7			)#
#N-(N)			#
#N#
E
[E, T, F]
[i, *, /, +, -, (, ), #]
T	[T*F, T/F, F]
E	[E+T, E-T, T]
F	[(E), i]T	[(, i, *, /]	[), i, *, /]
E	[(, i, *, +, -, /]	[), i, *, +, -, /]
F	[(, i]	[), i][null, >, >, >, >, null, >, >]
[<, >, >, >, >, <, >, >]
[<, >, >, >, >, <, >, >]
[<, <, <, >, >, <, >, >]
[<, <, <, >, >, <, >, >]
[<, <, <, <, <, <, =, null]
[null, >, >, >, >, null, >, >]
[<, <, <, <, <, <, null, =]Process finished with exit code 0

相关内容

热门资讯

FXGT:平台监管合规与全球市... 本文探讨FXGT平台的核心优势,重点分析其监管合规性和全球市场连接的整合价值。通过严格的合规框架,F...
原创 1... 写在文章前的声明:在本文之前的说明:本文中所列的投资信息,只是一个对基金资产净值进行排行的客观描述,...
原创 美... 2026 年 1 月 13 日,美国多家媒体集中披露两条重磅消息,中国美债持仓降至 6887 亿美元...
融资保证金比例重回100%:A... "两融余额突破2.67万亿!"当这个数字刷屏各大财经媒体时,监管层的一纸通知瞬间引爆市场——融资保证...
靠中式精酿9个月狂卖11亿,河... 不到两年时间,一群“微醺女孩”把一家成立44年的河南地方啤酒厂推到IPO门口。 1月13日,河南金星...
原创 黄... 哈喽大家好,今天小无带大家聊聊最近刷屏的抢金热潮!金饰价格飙涨不停,一条项链一夜涨1.5万还被疯抢,...
原创 虚... 小睿就来深扒“纸上黄金”的IPO迷局,Suplay冲刺港股欲成“收藏卡第一股”,靠米哈游IP赚足利润...
北京CBD千亿规模国际级商圈初... 央广网北京1月14日消息(记者 王进文)1月14日,记者从北京市朝阳区两会新闻发布会上了解到,北京商...
原创 9... 什么样的酒能赢得市场? 2026年开年,A股市场的“分裂感”格外清晰。一边,是上证指数稳步站上410...
北方稀土设备供应商,广泰真空上... 来源丨时代商业研究院 作者丨陆烁宜 编辑丨郑琳 时隔3个月,“超长验收”项目披露的数量却翻倍,沈阳广...
热点城市启动新年“第一拍” 民... 来源:21世纪经济报道 21世纪经济报道记者 张敏 1月14日,青岛2026年首场宅地拍卖落锤。在市...
啤酒卖不动了,中式精酿能救金星... 在中国啤酒行业,已经很久没有出现真正意义上的 " 新故事 " 了。 过去十余年,这个一度被视为现金牛...
小组第二出线!U23亚洲杯-李... 北京时间1月14日消息,2026年U23亚洲杯小组赛继续进行,在D组最后一轮争夺中,中国U23男足迎...
原创 反... 当地时间1月12日,一场不简单的会议在美国悄然召开,G7成员国的财长们、欧盟的代表、还有来自澳大利亚...
创尔生物再次折戟IPO:股东股... 近日,深耕胶原蛋白领域二十余年的广州创尔生物技术股份有限公司(以下简称“创尔生物”)在全国中小企业股...
仓储物流巨头普洛斯中国迎来女C... 1月14日,普洛斯集团(GLP Pte Ltd,简称“GLP”)宣布任命公司创始成员、中国物流仓储与...
耐心资本赋能新质生产力 成都高... 活动现场 图片来源:成都高新区提供 发布“双清单”,进行主题分享、项目路演等,搭建资本与产业精准对接...
40多年来广东制造爆款频出,董... “质量关乎两个生命:消费者的生命和企业的生命,广货的底气正是来自这份刻进骨子里的质量意识。”1月14...
世界经济论坛年度风险报告:全球... 财联社1月14日讯(编辑 史正丞)世界经济论坛周三发布的全球风险报告显示,涵盖关税、制裁等工具的地缘...
原创 果... 当地时间1月12日,特朗普在“真实社交”上甩出一记经贸重拳,宣称对所有与伊朗有商业往来的国家加征25...