视频加载失败

课程

338 字
约 1 分钟

2.1 赋值语句的语法分析

编译原理labs/lab02-syntax-analysis·更新于 2026-09-15

2.1 赋值语句的语法分析

1. 任务描述

本关任务:采用递归向下分析方法对赋值语句进行语法分析。

相关知识

为了完成本关任务,你需要掌握:

  1. 递归下降语法分析方法的算法思想。
  2. 语法分析树的构造。

编程要求

根据提示,在右侧编辑器补充代码。

测试说明

平台会对你编写的代码进行测试:

测试输入: 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
Profile Image of the Author
Sonder
好想要技术
这是公告标题
这只是一个公告
分类
标签
站点信息
构建平台
GitHub Actions
博客版本
Firefly v6.16.7
文章许可
CC BY-NC-SA 4.0
文章目录