编译原理-语法分析实验

从来没有写过关于课程内容的博客,这算是第一次吧

今天刚做了编译原理语法分析实验,感觉还挺有趣的写一写记录一下

参考

主要还是课堂内容,书本知识

编译原理 —— 递归下降分析法

实验内容

实验指导书就不整个贴了,下面是实验内容

1、对算术表达式文法:

E→TE'

E'→+TE'| -TE' |ε

T→FT'

T'→*FT'| /FT' |ε

F→(E) | id |num

构造其递归下降分析程序。

2、实验步骤

(1)求出每个非终结符的FIRST和FOLLOW集(在练习本上求出即可,不要求程序实现);

(2)构造递归下降分析程序;

(3)验证结果。

代码

关于编译原理的知识我也不补充了,刚学我还没搞明白呢

废话不多数直接上代码

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
package com.year21h1;

import java.util.Scanner;

/**
* @author: wnhyang
* @create: 2021-04-16 09:55
**/
public class Ex2 {
/**
* 算术表达式文法
* E→TE'
* E'→+TE'| -TE' |ε
* T→FT'
* T'→*FT'| /FT' |ε
* F→(E) | id |num
*/
static int index = 0;
static String s;
static StringBuilder sb = new StringBuilder();

public static void main(String[] args) throws Exception {

Scanner sc = new Scanner(System.in);
s = sc.next();
E();
System.out.println(sb);
}

static void E() throws Exception {
sb.append("E->TE'\t");
T();
Ep();
}

static void Ep() throws Exception {
if (!end() && (sym() == '+' || sym() == '-')) {
sb.append("E'->").append(sym()).append("TE'\t");
index++;
T();
Ep();
} else {
sb.append("E'->ε\t");
}

}

static void T() throws Exception {
sb.append("T->FT'\t");
F();
Tp();
}

static void Tp() throws Exception {
if (!end() && (sym() == '*' || sym() == '/')) {
sb.append("T'->").append(sym()).append("FT'\t");
index++;
F();
Tp();
} else {
sb.append("T'->ε\t");
}

}

static void F() throws Exception {
if (!end()) {
if (sym() == '(') {
sb.append("F->(E)\t");
index++;
E();
if (sym() == ')') {

index++;
} else {
throw new Exception("error");
}
} else if (sym() == 'i') {
index++;
if (sym() == 'd') {
sb.append("F->id\t");
index++;
} else {
throw new Exception("error");
}
} else if (sym() == 'n') {
index++;
if (sym() == 'u') {
index++;
if (sym() == 'm') {
sb.append("F->num\t");
index++;
} else {
throw new Exception("error");
}
} else {
throw new Exception("error");
}
} else {
throw new Exception("error");
}
}

}

/**
* 下标合法,当前下标字符,否则异常
*
* @return 当前字符
* @throws Exception
*/
static char sym() throws Exception {
if (index >= s.length()) {
throw new Exception("error");
}
return s.charAt(index);
}

/**
* 判断是否到达串尾
*
* @return
*/
static boolean end() {
return index == s.length();
}

}

输入:

(id+num)*num/(num-id)

输出:

E->TE' T->FT' F->(E) E->TE' T->FT' F->id T'->ε E'->+TE' T->FT' F->num T'->ε E'->ε T'->*FT' F->num T'->/FT' F->(E) E->TE' T->FT' F->num T'->ε E'->-TE' T->FT' F->id T'->ε E'->ε T'->ε E'->ε

本程序能输出输入串的构造过程(当然必须是合法可构造的),如果递归构造失败则会抛出异常

上面程序只看代码再结合给定的算术表达式就比较容易看懂了,但其实自己动手做不是那么容易,首先要理清其逻辑关系,然后写代码,这时往往总会会忽略一些细节,需要自己调试,直到自己满意

总结

能在繁忙或是说无聊的生活中找到自己喜欢并能投入进去的事实在是太幸福了