一、 实验目的

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

二、 实验内容

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<String> terSymbol = new ArrayList<>();// 终结符public static ArrayList<String> non_ter = new ArrayList<>();// 非终结符public static HashMap<String, List<String>> formula = new HashMap<>();//产生式public static HashMap<String, Set<String>[]> 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<String> 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<String> list = formula.get(non);//non这个非终结符对应的生成式for (String f : list) {// 对于每个式子fArrayList<String> 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<String>[] 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<String> 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<String> 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<String> 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<String> 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<String> 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

郑州大学编译原理实验三算符优先分析算法JAVA相关推荐

  1. java编程实现算符优先分析法,编译原理实验三-算符优先分析法

    编译原理实验3-算符优先分析法 #include #include #include #include #define SIZE 128 char priority[6][6]; //算符优先关系表数 ...

  2. 实验三 算符优先分析算法的设计与实现

    实验三 算符优先分析算法的设计与实现(8学时) 一. 实验目的 根据算符优先分析法,对表达式进行语法分析,使其能够判断一个表达式是否正确.通过算符优先分析方法的实现,加深对自下而上语法分析方法的理解. ...

  3. 编译原理 实验三 LR(1)分析法 Java

    1. 实验目的 构造 LR(1)分析程序,利用它进行语法分析,判断给出的符号串是否为该文法识别的句子,了解 LR(K)分析方法是严格的从左向右扫描,和自底向上的语法分析方法. 2. 实验内容 对下列文 ...

  4. 编译原理实验三 LR(1)分析法

    实验三 LR(1)分析法 构造 LR(1)分析程序,利用它进行语法分析,判断给出的符号串是否为该文 法识别的句子,了解 LR(K)分析方法是严格的从左向右扫描,和自底向上的 语法分析方法. 二.实验内 ...

  5. 编译原理实验(算符优先文法)

    work.h  1 #include<iostream>  2 #include<stdlib.h>  3 #include<stdio.h>  4 #includ ...

  6. 合工大 编译原理 实验三

    合工大 编译原理 实验三 LR(1) 分析法 本项目使用c++实现,利用Windows API制作了简易的UI界面. 具体功能如下: 支持查看文法,项目族,LR(1) 分析表,句子归约过程. 可使用包 ...

  7. 算符优先分析法-java实现

    算符优先分析器-java实现 一.判断是否是算符文法 算符文法定义:一个文法,如果它的任一产生式的右部都不含两个相继(并列)的非终结符,即不含如下形式的产生式右部:-QR-,则称该文法为算符文法 二. ...

  8. 算符优先分析算法及其代码实现

    1. 什么是算符优先分析算法? 这是一种经典的自底向上分析法,简单直观,并被广泛使用.开始主要是对表达式的分析,现在已不限于此,可以用于一大类上下文无关文法. 称为算符优先分析是因为这种方法是仿效算术 ...

  9. 编译原理系列之五 自底向上优先分析(2)-算符优先分析法

    算符优先分析法 1.基本概念 算符文法(OG):文法G中没有形如A=>···BC···的产生式,其中B.C为非终结符,则G为算符文法(operator grammar). 也就是说产生式的右部不 ...

  10. 【编译原理】Up-Down-算符优先分析

    宏观自下而上分析. 所谓自下而上分析,就是从输入串开始,逐步进行"归约",直至归约到文法的开始符号:或者说,从语法树的末端开始,步步向上"归约",直到根结点.我 ...

最新文章

  1. python实现快排算法(quicksort)
  2. ASP.NET生成静态页面的方法
  3. S3C6410 KeyPad驱动(上)
  4. 性能提升2.58倍!阿里最快KV存储引擎揭秘
  5. Android 开发工具类 02_DensityUtils
  6. FlasCC例子研究之Drawing补充
  7. NOIP2017洛谷P3953:逛公园(分层图最短路、dp、拓扑)
  8. Web的系统测试方法
  9. 用迭代法求方程cos(y)-y=0的一个实根
  10. MacOS系统离线安装包11.x-12.x
  11. 计算机导师问读研计划和后续计划,考研面试,问“研究生时期的规划”怎么回答急...
  12. C语言气温连续上升的天数,广西多地连阴雨天数破纪录 - 广西首页 -中国天气网...
  13. 祝萍:后疫情时代医美运营要以顾客体验为中心
  14. SNES 与 NES 游戏模拟机区别与 SNES Classic界面实现,
  15. 面试题汇总 (HTML与浏览器篇)
  16. 计算机无法打开压缩包,电脑打不开zip文件怎么打开
  17. 爬虫,第十次实战之线程池(梨视频下载)
  18. ios12完美深色模式插件_分屏插件更新支持 A12,一心二用真滴爽
  19. 海量数据处理问题汇总
  20. ArcGIS 同一要素图层合并

热门文章

  1. 如何测试蓝牙设备的延时
  2. Springboot 通过Jedis-clients 操作Redis
  3. 班级校园网页设计作业 静态HTML我的班级网页 DW班级网站模板 大学生简单班级网页作品代码 我的大学网页制作 学生班级网页设计作业
  4. JS 数字,金额 用逗号 隔开(数字格式化)
  5. 互联网dmz区_idc是什么行业(idc区和dmz区)
  6. 记一次生产事故排查——CPU高负载原因排查分析
  7. 基于RiskPariyBlackLitterman的因子择时
  8. 加工奶制品的生产计划
  9. 定时删除虚拟服务器快照,自动执行VMware快照并删除超过5天的快照
  10. 论文学习——基于滑动窗口预测的水位时间序列异常检测