本实验报告详述了编译原理中词法、语法与语义分析的过程和技术,并提供了完整的源代码示例。通过具体实现,加深对编译过程的理解。
附录C 编译程序实验
**实验目的**
用C语言对一个简单语言的子集编制一遍扫描的编译程序,以加深理解编译原理,并掌握实现方法和技术。
### 语法分析
#### C2.1 实验目的
编写递归下降解析程序,用于检查词法分析器提供的单词序列是否符合语法规则并进行结构分析。
#### C2.2 实验要求
利用C语言创建递归下降解析程序,对简单语言执行语法分析。待分析的简单语言包括算术表达式和赋值语句等基本元素。
### 语法制导翻译实验目的与要求
通过上机实习加深理解语法制导翻译原理,并掌握将识别出的语法成分转换为中间代码的方法。
采用递归下降法对算术表达式、赋值语句进行分析并生成四元式序列,输入是正确的单词串,输出则是三地址指令形式的四元式序列。
### 算法思想
1. 设置语义过程
- `emit` 函数:创建一个三地址语句,并将其送入到四元式表中。
四元式的结构如下:
```c
struct {
char result[8];
char arg1[8];
char op[8];
char ag2[8];
} quad[20];
- `newtemp` 函数:返回一个新的临时变量名,如T1, T2等。
```c
char *newtemp(void) {
static int k = 0;
char m[8], p[9];
itoa(++k, m, 10);
strcpy(p + 1, m);
p[0] = t;
return strdup(p);
}
```
2. 主程序示意图
- 主要流程图展示如何将输入的单词序列转换为四元式。
3. 函数 `lrparser`
在语法分析基础上插入语义动作,实现从输入串到四元式的翻译。在实验中仅对表达式和赋值语句进行处理。
```c
int lrparser() {
int schain = 0;
if (syn == 1) { // 开始符号为begin
scanner();
yucu();
if (syn == 6 && kk == 0)
printf(success\n);
else if(kk != 1 )
printf(缺少end 错误);
} else {
printf(非法开始错误);
kk = 1;
}
return schain;
}
```
4. 函数 `yucu`
调用语句分析函数进行循环处理,直到遇到结束符。
```c
int yucu() {
int schain=0;
while (syn == 26) {
scanner();
statement(); // 分析单个语句
}
return(schain);
}
```
5. 函数 `statement`
调用表达式分析函数,根据当前单词类型执行相应操作。
```c
int statement() {
int schain = 0;
switch (syn) {
case 10: // 标识符
strcpy(tt, token); scanner();
if(syn == 18 ) { // 赋值号
expression(); emit(tt,, , );
} else printf(缺少赋值号 错误);
}
return schain;
}
```
6. 函数 `expression`
分析表达式,生成相应的四元式。
```c
char *expression(void) {
char *tp, *ep2, *eplace;
eplace = term(); // 产生第一项
while (syn == 13 || syn == 14 ) {
strcpy(tp,newtemp());
emit(tp,eplace,+,term());
strcpy(eplace,tp);
}
return eplace;
}
```
7. 函数 `term`
分析乘除运算,递归调用自身或返回常量值。
```c
char *term() {
char *fplace;
if (syn == 11) { // 数字
itoa(sum, fplace, 10);
} else if(syn==27 ) { // 左括号
expression();
} else printf(错误);
return(fplace);
}
```
以上是整个实验的主要流程和核心代码。通过这些步骤,可以实现从简单的语言结构到四元式的转换过程。这有助于理解编译器设计中的关键概念和技术细节。