LL(1)语法分析(java)
来源:互联网 发布:java在线视频网站源码 编辑:程序博客网 时间:2024/06/01 10:06
转:http://blog.csdn.net/new_one_object/article/details/50670624
一、程序设计题目与说明
通过运用编译原理课程所学知识,实现LL(1)文法的语法分析程序,当任意输入一个文法符号串,通过程序中先设定好确定的LL(1)预测分析表,按照预测分析算法对输入串进行语法分析,判断其是否为符合文法规范的一个句子。如果符合文法规范则输出符号串、剩余输入串、规则等信息,否则输出错误信息
(自己加的,便于理解整个流程)简述:
init(),--》根节点E进栈,打印一行信息,不再用
totalControlProgram();,--》
1》第一步判断flag是true 则证明栈区有值,继续往下走,为false则栈区没有元素,退出
2》第二步判断栈顶元素是否是终结符,是终结符则直接pop出栈,缓冲区首字符也移除,打印输出信息
3》第三部判断栈顶元素是否为#有则匹配成功,flag设为false退出程序
4》第三步判断当前元素不为空,(如果到了这步,代表前面已经不是终结符#)把栈顶出栈,然后把得到的矩阵元素字符化后入栈
然后一步步往下走,遇见终结符就到《2》,遇到#就到《3》,遇到非终结符到《4》
二、全部代码
package downloadtest;import java.util.Stack;public class analyse { // 加入同步符号的LL(1)分析表 private String[][] analysisTable = new String[][] { { "TZ", "", "", "TZ", "synch", "synch" }, { "", "+TZ", "", "", "ε", "ε" }, { "FY", "synch", "", "FY", "synch", "synch" }, { "", "ε", "*FY", "", "ε", "ε" }, { "i", "synch", "synch", "(E)", "synch", "synch" } }; // 存储终结符 private String[] VT = new String[] { "i", "+", "*", "(", ")", "#" }; // 存储非终结符 private String[] VN = new String[] { "E", "Z", "T", "Y", "F" }; // 输入串 private StringBuilder strToken; // 分析栈 private Stack<String> stack = new Stack<String>(); // a保存从输入串中读取的一个输入符号,当前符号 private String a = null; // X中保存stack栈顶符号 private String X = null; // flag标志预测分析是否成功 private boolean flag = true; // 记录输入串中当前字符的位置 private int cur = 0; // 记录步数 private int count = 0; public analyse(StringBuilder strToken) { this.strToken = strToken; init(); totalControlProgram(); printf(); } // 初始化 protected void init() { strToken.append("#"); stack.push("#"); System.out.println("步骤\t " + "符号栈\t\t " + "输入串 \t" + "所用产生式 "); stack.push("E"); curCharacter(); System.out.printf("%-6d %-20s %6s \n", count, stack.toString(), strToken.substring(cur, strToken.length())); } // 读取当前栈顶符号 protected String stackPeek() { X = stack.peek();//栈顶元素(size-1) return X; } // 返回输入串中当前位置的字母 private String curCharacter() { a = String.valueOf(strToken.charAt(cur));//默认0位为第一个字符 return a; } // 判断X是否是终结符 protected boolean XisVT() { for (int i = 0; i < (VT.length - 1); i++) { if (VT[i].equals(X)) { return true; } } return false; } // 查找X在非终结符中分析表中的横坐标 protected String VNTI() { int Ni = 0, Tj = 0; for (int i = 0; i < VN.length; i++) { if (VN[i].equals(X)) {//非终结符非终结符行比较栈顶元素 Ni = i;//记录行号 } } for (int j = 0; j < VT.length; j++) { if (VT[j].equals(a)) {//终结符矩阵列比对缓冲区首字符 Tj = j;//记录列号 } } return analysisTable[Ni][Tj];//得到行号列号,找到矩阵上唯一的元素,即表达式,推进栈顶 } // 判断M[A,a]={X->X1X2...Xk} // 把X1X2...Xk推进栈 // X1X2...Xk=ε,不推什么进栈 protected boolean productionType() { if (VNTI() != "") { return true; } return false; } // 推进stack栈 protected void pushStack() { stack.pop();//当前元素出栈,加入新的元素 String M = VNTI(); String ch; for (int i = (M.length() - 1); i >= 0; i--) { ch = String.valueOf(M.charAt(i));//字符串变成字符依次加入栈,反向,极为栈顶 stack.push(ch); } System.out.printf("%-6d %-20s %6s %-1s->%-12s\n", (++count), stack.toString(), strToken.substring(cur, strToken.length()), X, M); } // 总控程序 protected void totalControlProgram() { while (flag == true) {//无限循环直至,最终栈空间为# stackPeek();//得到栈顶元素X有值了E if (XisVT() == true) {//判断是终结符 if (X.equals(a)) {//栈顶元素与缓冲区首字符匹配 cur++;//缓冲区首位元素+1 a = curCharacter();//得到下一位字符 stack.pop();//缓冲区元素为终结符切等于栈顶字符,那么直接pop,打印信息 System.out.printf("%-6d %-20s %6s \n", (++count), stack.toString(), strToken.substring(cur, strToken.length())); } else { ERROR(); } } else if (X.equals("#")) {//判断是否为最后一个# if (X.equals(a)) {//缓冲区元素也是#那么匹配成功 flag = false; } else { ERROR(); } } else if (productionType() == true) {//判断矩阵定位的地方有元素 if (VNTI().equals("synch")) {//判断是否为同步字符 ERROR();//无法分析 } else if (VNTI().equals("ε")) {//判断是否为空 stack.pop();//是空则,直接把这个pop出,用下一个栈顶元素求 System.out.printf("%-6d %-20s %6s %-1s->%-12s\n", (++count), stack.toString(), strToken.substring(cur, strToken.length()), X, VNTI()); } else {//有值,且就是这条线 pushStack(); } } else {//什么都不是则,文法错误,不可分析 ERROR(); } } } // 出现错误 protected void ERROR() { System.out.println("输入串错误,分析中断"); System.exit(0); } // 打印存储分析表 protected void printf() { if (flag == false) { System.out.println("========分析成功"); } else { System.out.println("========分析失败"); } } public static void main(String[] args) { StringBuilder strToken = new StringBuilder("i*i+i"); new analyse(strToken); }}
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
三、测试数据和实验结果分析
当输入串为 “i+)+i*i”时,可知输入串存在非法符号“)”,程序分析结果如下图所示:
当输入串为“i+i+i*i”时,程序分析结果如下图所示:
0 0
- LL(1)语法分析(java)
- LL(1)语法分析
- LL(1)语法分析
- LL(1)语法分析
- 自上而下语法分析LL(1)
- LL(1)语法分析<转>
- 【C++】C++实现LL(1)语法分析
- LL(1)语法分析程序
- 用JAVA实现LL(1)文法语法分析程序
- LL(1)语法分析实验报告
- 输入输出LL(1)语法分析程序
- 一个基于LL(1)文法的语法分析程序
- 自顶向下的语法分析LL(1)
- 词法分析 与 LL(1)语法分析
- 语法分析之LL(1)分析法
- 1000-输入输出LL(1)语法分析程序
- sicily1000. 输入输出LL(1)语法分析程序
- sicily1001. 输入输出LL(1)语法分析程序 **
- nginx+php多域名配置的方法
- angular4随记——angular4使用datatable
- 抽象类和接口的区别
- SQL 各种join关联查询
- 一台服务器同时运行多个tomcat的简易区分方法
- LL(1)语法分析(java)
- python pandas学习笔记
- fir.im 持续集成技术实践
- 这些老外的开源技术养活了很多国产软件
- 最短路算法dijkstra算法学习
- 1——计算字符串最后一个单词的长度,单词以空格隔开
- Rotate 旋转loading实现对比
- 详细的Oracle11g的 图形安装步骤。
- 从两道经典试题谈C/C++中联合体(union)的使用