java ll_LL(1)语法分析(java)

这是一个Java实现的LL(1)语法分析程序,用于判断输入串是否符合文法规范。程序通过预设的LL(1)预测分析表进行分析,包括初始化、判断栈区元素、匹配终结符和非终结符等步骤。当输入串符合文法时,输出相关信息;否则,输出错误信息。
摘要由CSDN通过智能技术生成

LL(1)语法分析(java)

LL(1)语法分析(java)

转: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 stack = new Stack();

// 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

1641

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”时,可知输入串存在非法符号“)”,程序分析结果如下图所示:

36e125e34990889095f4d1537cd4ee2c.png

当输入串为“i+i+i*i”时,程序分析结果如下图所示:

19dc17b31abf4faf0cdf9a9fe0f8fa97.png

LL(1)语法分析(java)相关教程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值