设计一个中间代码生成器,要求,1、考虑下述语法制导定义中文法,采用递归子程序法,改写文法,构造语法分析程序; 2、考虑下述语法制导定义中语义规则,改写语法分析程序,构造三地址代码生成程序。
时间: 2024-05-01 11:23:32 浏览: 137
语义分析及中间代码生成程序设计原理与实现技术--实验报告及源代码 北京交通大学.doc
为了方便起见,我们在此假定已经有了一个词法分析器,可以将输入的源代码转换为词法单元序列。
以下是一个简单的语法制导定义和相应的文法:
1. 语法制导定义
```
expr → term addop expr {expr.value = addop.func(term.value, expr1.value)}
| term {expr.value = term.value}
term → factor mulop term {term.value = mulop.func(factor.value, term1.value)}
| factor {term.value = factor.value}
factor → ( expr ) {factor.value = expr.value}
| number {factor.value = number.value}
```
2. 对应的文法:
```
expr → term expr1
expr1 → addop term expr1 | ε
term → factor term1
term1 → mulop factor term1 | ε
factor → ( expr ) | number
```
接下来,我们可以使用递归子程序法来编写语法分析程序。在语法分析过程中,我们需要注意计算出每个非终结符的值,并将其传递给父级节点。
下面是相应的语法分析程序:
```
int expr() {
int value = term();
return expr1(value);
}
int expr1(int value) {
if (lookahead == ADD_OP) {
match(ADD_OP);
int termValue = term();
int result = add(value, termValue);
return expr1(result);
} else {
return value;
}
}
int term() {
int value = factor();
return term1(value);
}
int term1(int value) {
if (lookahead == MUL_OP) {
match(MUL_OP);
int factorValue = factor();
int result = mul(value, factorValue);
return term1(result);
} else {
return value;
}
}
int factor() {
int value;
if (lookahead == LEFT_PAREN) {
match(LEFT_PAREN);
value = expr();
match(RIGHT_PAREN);
} else if (lookahead == NUMBER) {
value = parseNumber();
match(NUMBER);
} else {
// syntax error
}
return value;
}
```
在上述程序中,`match()` 函数用于将当前的词法单元与所期望的单元进行匹配,如果匹配成功,则向前移动一个单元。`parseNumber()` 函数用于将当前的词法单元解析为一个整数值。
接下来,我们可以将上述语法分析程序改写为三地址代码生成程序。在代码生成过程中,我们需要记录每个表达式的结果,并生成相应的三地址代码。
以下是相应的三地址代码生成程序:
```
int expr() {
int t1 = term();
return expr1(t1);
}
int expr1(int value) {
if (lookahead == ADD_OP) {
match(ADD_OP);
int t1 = term();
int t2 = newTemp();
genCode(t2, value, t1, "+");
return expr1(t2);
} else {
return value;
}
}
int term() {
int t1 = factor();
return term1(t1);
}
int term1(int value) {
if (lookahead == MUL_OP) {
match(MUL_OP);
int t1 = factor();
int t2 = newTemp();
genCode(t2, value, t1, "*");
return term1(t2);
} else {
return value;
}
}
int factor() {
int value;
if (lookahead == LEFT_PAREN) {
match(LEFT_PAREN);
value = expr();
match(RIGHT_PAREN);
} else if (lookahead == NUMBER) {
value = parseNumber();
match(NUMBER);
} else {
// syntax error
}
return value;
}
int newTemp() {
static int count = 0;
return count++;
}
void genCode(int result, int arg1, int arg2, char op) {
printf("%d = %d %c %d\n", result, arg1, op, arg2);
}
```
在上述程序中,`newTemp()` 函数用于生成一个新的临时变量名,`genCode()` 函数用于生成相应的三地址代码并将其输出到屏幕上。
阅读全文