课程
338 字
约 1 分钟
大三下
2.1 赋值语句的语法分析
编译原理labs/lab02-syntax-analysis·更新于 2026-09-15
2.1 赋值语句的语法分析
1. 任务描述
本关任务:采用递归向下分析方法对赋值语句进行语法分析。
相关知识
为了完成本关任务,你需要掌握:
- 递归下降语法分析方法的算法思想。
- 语法分析树的构造。
编程要求
根据提示,在右侧编辑器补充代码。
测试说明
平台会对你编写的代码进行测试:
测试输入: demo4.txt
(文件内容为:x:=x+y*(a-b)/2)
预期输出:
> 赋值语句
| > 标识符
| | > x
| > :=
| > 表达式
| | > 项
| | | > 因子
| | | | > 标识符
| | | | | > x
| | > 加减运算符
| | | > +
| | > 项
| | | > 因子
| | | | > 标识符
| | | | | > y
| | | > 乘除运算符
| | | | > *
| | | > 因子
| | | | > (
| | | | > 表达式
| | | | | > 项
| | | | | | > 因子
| | | | | | | > 标识符
| | | | | | | | > a
| | | | | > 加减运算符
| | | | | | > -
| | | | | > 项
| | | | | | > 因子
| | | | | | | > 标识符
| | | | | | | | > b
| | | | > )
| | | > 乘除运算符
| | | | > /
| | | > 因子
| | | | > 无符号整数
| | | | | > 2
开始你的任务吧,祝你成功!
2. 我的回答
文件 main5.cpp:
#include "getsym.h"
struct treeNode {
string element;
vector<treeNode* > child;
explicit treeNode(string e) {
element = e; //NOLINT
for (auto & it : child)
it = nullptr;
}
};
void assi_sen(treeNode* tn); //赋值语句
void expression(treeNode* tn); //表达式
void item(treeNode* tn); //项
void factor(treeNode* tn); //因子
void printTreeNode(treeNode *root, int level)
{
if (root != nullptr) {
for (int i = 0; i < level; ++i)
cout << "| ";
cout << "> " << root->element << endl;
for (auto & it : root->child)
printTreeNode(it, level+1);
}
}
string sym;
/*
<赋值语句> ::= <标识符>:=<表达式>
*/
void assi_sen(treeNode* tn)
{
if (sym == "identifier") {
auto *idt = new treeNode(debugId);
tn->child.push_back(new treeNode("标识符"));
tn->child.back()->child.push_back(idt);
string tmp = debugId; //保存待赋值的变量
sym = GETSYM();
if (sym == ":=") {
tn->child.push_back(new treeNode(":="));
sym = GETSYM();
auto *expressiont = new treeNode("表达式");
tn->child.push_back(expressiont);
expression(expressiont);
} else cout<<"error"; //不是变量赋值
} else cout<<"error";
}
/*
<表达式> ::= [+|-]<项>{<加法运算符><项>}
*/
/*
<表达式> ::= [+|-]<项>{<加减运算符><项>}
*/
/*
<表达式> ::= [+|-]<项>{<加减运算符><项>}
*/
void expression(treeNode* tn)
{
// 1. 处理可选的正负号 [+|-]
if (sym == "+" || sym == "-") {
tn->child.push_back(new treeNode(sym));
sym = GETSYM();
}
// 2. 处理必须存在的 <项>
auto *itemt = new treeNode("项");
tn->child.push_back(itemt);
item(itemt);
// 3. 处理循环部分 {<加减运算符><项>}
while (sym == "+" || sym == "-") {
auto *opt = new treeNode("加减运算符");
tn->child.push_back(opt);
opt->child.push_back(new treeNode(sym));
sym = GETSYM();
auto *itemt2 = new treeNode("项");
tn->child.push_back(itemt2);
item(itemt2);
}
}
/*
<项> ::= <因子>{<乘除运算符><因子>}
*/
void item(treeNode* tn)
{
//此处添加代码
// 1. 处理必须存在的 <因子>
auto *factort = new treeNode("因子");
tn->child.push_back(factort);
factor(factort);
// 2. 处理循环部分 {<乘除运算符><因子>}
while (sym == "*" || sym == "/") {
auto *opt = new treeNode("乘除运算符");
tn->child.push_back(opt);
opt->child.push_back(new treeNode(sym));
sym = GETSYM();
auto *factort2 = new treeNode("因子");
tn->child.push_back(factort2);
factor(factort2);
}
}
/*
<因子> ::= <标识符>|<无符号整数>|'('<表达式>')'
*/
void factor(treeNode* tn)
{
if (sym == "identifier" || sym == "number") {
string tmp;
treeNode *idt;
if (sym == "identifier") {
tmp = "标识符";
idt = new treeNode(debugId);
}
else {
tmp = "无符号整数";
idt = new treeNode(debugNum);
}
tn->child.push_back(new treeNode(tmp));
tn->child.back()->child.push_back(idt);
sym = GETSYM();
}
else if (sym == "(") {
tn->child.push_back(new treeNode("("));
sym = GETSYM();
auto *expressiont = new treeNode("表达式");
tn->child.push_back(expressiont);
expression(expressiont);
if (sym == ")") {
tn->child.push_back(new treeNode(")"));
sym = GETSYM();
}
else cout<<"error"; //因子中包含的表达式的错误结束
}
else return;
}
int main() {
integerArray.clear();
identifierArray.clear();
streambuf *stdin_backup = cin.rdbuf(); //备份标准输入流
string fileinname;
cin >> fileinname;
fcin.open(fileinname);
if (!fcin.is_open()) {
cout << "failed to open " << fileinname << endl;
return 0;
}
cin.rdbuf(fcin.rdbuf()); //将cin重定向到文件
auto *assi_sent = new treeNode("赋值语句");
sym=GETSYM();
assi_sen(assi_sent);
printTreeNode(assi_sent, 0);
cin.rdbuf(stdin_backup);
fcin.close();
//Interpret();
return 0;
}
文件 demo4.txt:
x:=x+y*(a-b)/2
文件 demo5.txt:
x:=(-x)*(5+b)/(c-d)+799
文件 demo6.txt:
x:=-a+5*4












