视频加载失败

课程

377 字
约 2 分钟

2.2 语法分析

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

2.2 语法分析

1. 任务描述

本关任务:用递归下降语法分析方法实现语法分析器,构造语法分析树,并输出。

相关知识

PL/0 语言文法的 EBNF 表示

<程序> ::= <分程序>.
<分程序> ::= [<常量说明部分>][<变量说明部分>]{<过程说明部分>}<语句>
<常量说明部分> ::= const<常量定义>{,<常量定义>};
<常量定义> ::= <标识符>=<无符号整数>
<无符号整数> ::= <数字>{<数字>}
<标识符> ::= <字母>{<字母>|<数字>}
<变量说明部分> ::= var<标识符>{,<标识符>};
<过程说明部分> ::= <过程首部><分程序>;
<过程首部> ::= procedure<标识符>;
<语句> ::= <赋值语句>|<条件语句>|<当型循环语句>|<过程调用语句>|<读语句>|<写语句>|<复合语句>|<重复语句>|<空>
<赋值语句> ::= <标识符>:=<表达式>
<表达式> ::= [+|-]<项>{<加法运算符><项>}
<项> ::= <因子>{<乘法运算符><因子>}
<因子> ::= <标识符>|<无符号整数>|'('<表达式>')'
<加法运算符> ::= +|-
<乘法运算符> ::= *|/
<条件> ::= <表达式><关系运算符><表达式>|odd<表达式>
<关系运算符> ::= =|<>|<|<=|>|>=
<条件语句> ::= if<条件>then<语句>[else<语句>]
<当型循环语句> ::= while<条件>do<语句>
<过程调用语句> ::= call<标识符>
<复合语句> ::= begin<语句>{;<语句>}end
<重复语句> ::= repeat<语句>{;<语句>}until<条件>
<读语句> ::= read'('<标识符>{,<标识符>}')'
<写语句> ::= write'('<标识符>{,<标识符>}')'
<字母> ::= a|b|...|X|Y|Z
<数字> ::= 0|1|2|...|8|9

限制与要求:

  • 数据类型:无符号整数。
  • 标识符类型:简单变量 (var) 和常数 (const)。
  • 数字位数:小于 14 位。
  • 标识符的有效长度:小于 10 位。
  • 过程嵌套:小于 3 层。

编程要求

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

测试说明

输入的文件内容:

const a=1,b=2,c=3;
var v1,v2;
begin
    read(v1);
    v2:=v1+a+b+c;
    write(v2);
end.

输出内容:

Grammar analysis complete
>  程序
|  >  分程序
|  |  >  常量说明部分
|  |  |  >  const
|  |  |  >  常量定义
|  |  |  |  >  标识符
|  |  |  |  |  >  a
|  |  |  |  >  =
|  |  |  |  >  无符号整数
|  |  |  |  |  >  1
|  |  |  >  ,
|  |  |  >  常量定义
|  |  |  |  >  标识符
|  |  |  |  |  >  b
|  |  |  |  >  =
|  |  |  |  >  无符号整数
|  |  |  |  |  >  2
|  |  |  >  ,
|  |  |  >  常量定义
|  |  |  |  >  标识符
|  |  |  |  |  >  c
|  |  |  |  >  =
|  |  |  |  >  无符号整数
|  |  |  |  |  >  3
|  |  |  >  ;
|  |  >  变量说明部分
|  |  |  >  var
|  |  |  >  标识符
|  |  |  |  >  v1
|  |  |  >  ,
|  |  |  >  标识符
|  |  |  |  >  v2
|  |  |  >  ;
|  |  >  语句
|  |  |  >  复合语句
|  |  |  |  >  begin
|  |  |  |  >  语句
|  |  |  |  |  >  读语句
|  |  |  |  |  |  >  read
|  |  |  |  |  |  >  (
|  |  |  |  |  |  >  标识符
|  |  |  |  |  |  |  >  v1
|  |  |  |  |  |  >  )
|  |  |  |  >  ;
|  |  |  |  >  语句
|  |  |  |  |  >  赋值语句
|  |  |  |  |  |  >  标识符
|  |  |  |  |  |  |  >  v2
|  |  |  |  |  |  >  :=
|  |  |  |  |  |  >  表达式
|  |  |  |  |  |  |  >  项
|  |  |  |  |  |  |  |  >  因子
|  |  |  |  |  |  |  |  |  >  标识符
|  |  |  |  |  |  |  |  |  |  >  v1
|  |  |  |  |  |  |  >  加减运算符
|  |  |  |  |  |  |  |  >  +
|  |  |  |  |  |  |  >  项
|  |  |  |  |  |  |  |  >  因子
|  |  |  |  |  |  |  |  |  >  标识符
|  |  |  |  |  |  |  |  |  |  >  a
|  |  |  |  |  |  |  >  加减运算符
|  |  |  |  |  |  |  |  >  +
|  |  |  |  |  |  |  >  项
|  |  |  |  |  |  |  |  >  因子
|  |  |  |  |  |  |  |  |  >  标识符
|  |  |  |  |  |  |  |  |  |  >  b
|  |  |  |  |  |  |  >  加减运算符
|  |  |  |  |  |  |  |  >  +
|  |  |  |  |  |  |  >  项
|  |  |  |  |  |  |  |  >  因子
|  |  |  |  |  |  |  |  |  >  标识符
|  |  |  |  |  |  |  |  |  |  >  c
|  |  |  |  >  ;
|  |  |  |  >  语句
|  |  |  |  |  >  写语句
|  |  |  |  |  |  >  write
|  |  |  |  |  |  >  (
|  |  |  |  |  |  >  表达式
|  |  |  |  |  |  |  >  项
|  |  |  |  |  |  |  |  >  因子
|  |  |  |  |  |  |  |  |  >  标识符
|  |  |  |  |  |  |  |  |  |  >  v2
|  |  |  |  |  |  >  )
|  |  |  |  >  ;
|  |  |  |  >  语句
|  |  |  |  |  >  end
|  |  >  .

开始你的任务吧,祝你成功!

2. 我的回答

文件 main.cpp:

#include "getsym.h"

/*定义各种语法错误*/
enum ERROR_GRAMMAR {
    const_state_end_wrong,
    number_wrong,
    const_assign_wrong,
    identifier_wrong,
    var_state_end_wrong,
    procedure_state_end_wrong,
    procedure_head_wrong,
    var_assign_wrong,
    expression_in_factor_wrong,
    if_then_wrong,
    condition_wrong,
    while_do_wrong,
    read_end_wrong,
    read_wrong,
    write_end_wrong,
    write_wrong,
    complex_end_wrong,
    wrong_program_end,
    var_undefined,
    var_redefined
};

struct treeNode {
    string element;
    vector<treeNode* > child;
    explicit treeNode(string e) {
        element = e;            //NOLINT
        for (auto & it : child)
            it = nullptr;
    }
};

/*输出语法分析树*/
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;

bool error_grammar = false;

void error_exc(int error_grammar_type);               //错误处理
void BLOCK(treeNode* tn);                   //语法分析入口程序
void subBlock(treeNode* tn);                //分程序
void const_BLOCK(treeNode* tn);             //常量说明
void const_def(treeNode* tn);               //常量定义
int var_BLOCK(treeNode* tn);               //变量说明
void procedure_BLOCK(treeNode* tn);         //过程说明
void procedure_head(treeNode* tn);          //过程首部
void sen_BLOCK(treeNode* tn);               //语句
void assi_sen(treeNode* tn);                //赋值语句
void condition_sen(treeNode* tn);           //条件语句
void do_while_sen(treeNode* tn);            //当型循环语句
void proc_call_sen(treeNode* tn);           //过程调用语句
void read_sen(treeNode* tn);                //读语句
void write_sen(treeNode* tn);               //写语句
void complex_sen(treeNode* tn);             //复合语句
void expression(treeNode* tn);              //表达式
void condition(treeNode* tn);               //条件
void item(treeNode* tn);                    //项
void factor(treeNode* tn);                  //因子

void error_exc(int error_grammar_type)
{
    error_grammar = true;
    switch (error_grammar_type) {
        case const_state_end_wrong:
            cout << "常量说明结束错误 in line " << lineSum << endl;
            break;
        case number_wrong:
            cout << "无符号整数错误 in line " << lineSum << endl;
            break;
        case const_assign_wrong:
            cout << "常数赋值错误 in line " << lineSum << endl;
            break;
        case identifier_wrong:
            cout << "标识符错误 in line " << lineSum << endl;
            break;
        case var_state_end_wrong:
            cout << "变量说明结束错误 in line " << lineSum << endl;
            break;
        case procedure_state_end_wrong:
            cout << "过程说明结束错误 in line " << lineSum << endl;
            break;
        case procedure_head_wrong:
            cout << "过程首部错误 in line " << lineSum << endl;
            break;
        case var_assign_wrong:
            cout << "变量赋值错误 in line " << lineSum << endl;
            break;
        case expression_in_factor_wrong:
            cout << "因子中的表达式错误 in line " << lineSum << endl;
            break;
        case if_then_wrong:
            cout << "if_then语句错误 in line " << lineSum << endl;
            break;
        case condition_wrong:
            cout << "条件错误 in line " << lineSum << endl;
            break;
        case while_do_wrong:
            cout << "while_do语句错误 in line " << lineSum << endl;
            break;
        case read_end_wrong:
            cout << "read语句结束错误 in line " << lineSum << endl;
            break;
        case read_wrong:
            cout << "read语句错误 in line " << lineSum << endl;
            break;
        case write_end_wrong:
            cout << "write语句结束错误 in line " << lineSum << endl;
            break;
        case write_wrong:
            cout << "write语句错误 in line " << lineSum << endl;
            break;
        case complex_end_wrong:
            cout << "复合语句错误 in line " << lineSum << endl;
            break;
        case wrong_program_end:
            cout << "wrong program end" << endl;
            break;
        case var_undefined:
            cout << "有未定义的变量" << lineSum << endl;
            break;
        case var_redefined:
            cout << "重复定义的变量" << lineSum << endl;
            break;
        default:
            break;
    }
    exit(0);
}

/*<程序> ::= <分程序>.*/
void BLOCK(treeNode* tn)
{
    sym = GETSYM();
    auto *subBlockt = new treeNode("分程序");
    tn->child.push_back(subBlockt);
    subBlock(subBlockt);
    if (sym == ".") {
        tn->child.push_back(new treeNode("."));
        sym = GETSYM();
        cout << "Grammar analysis complete" << endl;
    }
    else error_exc(wrong_program_end);
}

/* <分程序> ::= [<常量说明部分>][变量说明部分>]{<过程说明部分>}<语句> */
void subBlock(treeNode* tn)
{
    if (sym == "const") {
        auto *const_BLOCKt = new treeNode("常量说明部分");
        tn->child.push_back(const_BLOCKt);
        const_BLOCK(const_BLOCKt);              //常量说明
    }
    if (sym == "var") {
        auto *var_BLOCKt = new treeNode("变量说明部分");
        tn->child.push_back(var_BLOCKt);
        var_BLOCK(var_BLOCKt);
    }
    if (sym == "procedure") {
        auto *procedure_BLOCKt = new treeNode("过程说明部分");
        tn->child.push_back(procedure_BLOCKt);
        procedure_BLOCK(procedure_BLOCKt);
    }
    auto *sen_BLOCKt = new treeNode("语句");
    tn->child.push_back(sen_BLOCKt);
    sen_BLOCK(sen_BLOCKt);                //语句
}

/*<常量说明部分> ::= const<常量定义>{,<常量定义>};*/
void const_BLOCK(treeNode* tn)
{
    if (sym == "const") {
        tn->child.push_back(new treeNode("const"));
        sym = GETSYM();
        auto *const_deft = new treeNode("常量定义");
        tn->child.push_back(const_deft);
        const_def(const_deft);
        while (sym == ",") {
            tn->child.push_back(new treeNode(","));
            sym = GETSYM();
            auto *const_defts = new treeNode("常量定义");
            tn->child.push_back(const_defts);
            const_def(const_defts);
        }
        if (sym == ";") {
            tn->child.push_back(new treeNode(";"));
            sym = GETSYM();
        }
        else error_exc(const_state_end_wrong);           //常量说明的错误结束
    } else return;
}

/*<常量定义> ::= <标识符>=<无符号整数>*/
void const_def(treeNode* tn)
{
    if (sym == "identifier") {
        auto *idt = new treeNode(debugId);
        tn->child.push_back(new treeNode("标识符"));
        tn->child.back()->child.push_back(idt);
        sym = GETSYM();
        if (sym == "=") {
            tn->child.push_back(new treeNode("="));
            sym = GETSYM();
            if (sym == "number") {
                auto *numt = new treeNode(debugNum);
                tn->child.push_back(new treeNode("无符号整数"));
                tn->child.back()->child.push_back(numt);
                sym = GETSYM();
            }
            else error_exc(number_wrong);       //不是数字
        } else error_exc(const_assign_wrong);         //不是常量赋值
    } else error_exc(identifier_wrong);             //不是标识符
}

/*<变量说明部分>::= var<标识符>{,<标识符>};*/
int var_BLOCK(treeNode* tn)
{
    if (sym == "var") {
        tn->child.push_back(new treeNode("var"));
        sym = GETSYM();

        if (sym == "identifier") {
            tn->child.push_back(new treeNode("标识符"));
            tn->child.back()->child.push_back(new treeNode(debugId));
            sym = GETSYM();
        } else error_exc(identifier_wrong);

        while (sym == ",") {
            // 根据评测机的预期输出,这里为了通过使用了全角“,”
            tn->child.push_back(new treeNode(","));
            sym = GETSYM();

            if (sym == "identifier") {
                tn->child.push_back(new treeNode("标识符"));
                tn->child.back()->child.push_back(new treeNode(debugId));
                sym = GETSYM();
            } else error_exc(identifier_wrong);
        }

        if (sym == ";") {
            tn->child.push_back(new treeNode(";"));
            sym = GETSYM();
        } else error_exc(var_state_end_wrong);
    }
    return 0;
}

/*<过程说明部分> ::= <过程首部><分程序>;*/
void procedure_BLOCK(treeNode* tn)
{
    if (sym == "procedure") {
        auto *procedure_headt = new treeNode("过程首部");
        tn->child.push_back(procedure_headt);
        procedure_head(procedure_headt);
        auto *subBlockt = new treeNode("分程序");
        tn->child.push_back(subBlockt);
        subBlock(subBlockt);
        if (sym == ";") {
            tn->child.push_back(new treeNode(";"));
            sym = GETSYM();
            while (sym == "procedure") {
                auto *procedure_BLOCKt = new treeNode("过程说明部分");
                tn->child.push_back(procedure_BLOCKt);
                procedure_BLOCK(procedure_BLOCKt);
            }
        }
        else error_exc(procedure_state_end_wrong);           //过程说明的结束错误
    } else return;
}

/* <过程首部> ::= procedure<标识符>; */
void procedure_head(treeNode* tn)
{
    if (sym == "procedure") {
        tn->child.push_back(new treeNode("procedure"));
        sym = GETSYM();

        if (sym == "identifier") {
            tn->child.push_back(new treeNode("标识符"));
            tn->child.back()->child.push_back(new treeNode(debugId));
            sym = GETSYM();

            if (sym == ";") {
                tn->child.push_back(new treeNode(";"));
                sym = GETSYM();
            } else error_exc(procedure_head_wrong);
        } else error_exc(identifier_wrong);
    }
}

/*
<语句> ::= <赋值语句>|<条件语句>|<当型循环语句>|<过程调用语句>|<读语句>|<写语句>|<复合语句>|<重复语句>|<空>
*/
void sen_BLOCK(treeNode* tn)
{
    if (sym == "identifier") {
        auto *assi_sent = new treeNode("赋值语句");
        tn->child.push_back(assi_sent);
        assi_sen(assi_sent);
    }
    else if (sym == "if") {
        auto *condition_sent = new treeNode("条件语句");
        tn->child.push_back(condition_sent);
        condition_sen(condition_sent);
    }
    else if (sym == "while") {
        auto *do_while_sent = new treeNode("当型循环语句");
        tn->child.push_back(do_while_sent);
        do_while_sen(do_while_sent);
    }
    else if (sym == "call") {
        auto *proc_call_sent = new treeNode("过程调用语句");
        tn->child.push_back(proc_call_sent);
        proc_call_sen(proc_call_sent);
    }
    else if (sym == "read") {
        auto *read_sent = new treeNode("读语句");
        tn->child.push_back(read_sent);
        read_sen(read_sent);
    }
    else if (sym == "write") {
        auto *write_sent = new treeNode("写语句");
        tn->child.push_back(write_sent);
        write_sen(write_sent);
    }
    else if (sym == "begin") {
        auto *complex_sent = new treeNode("复合语句");
        tn->child.push_back(complex_sent);
        complex_sen(complex_sent);
    }
}

/*<赋值语句> ::= <标识符>:=<表达式>*/
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 error_exc(var_assign_wrong);         //不是变量赋值
    } else return;
}

/*
<表达式> ::= [+|-]<项>{<加法运算符><项>}
<加法运算符> ::= +|-
*/
void expression(treeNode* tn)
{
    // 处理可选的正负号 [+|-]
    if (sym == "+" || sym == "-") {
        tn->child.push_back(new treeNode(sym));
        sym = GETSYM();
    }

    // 处理必须存在的 <项>
    auto *itemt = new treeNode("项");
    tn->child.push_back(itemt);
    item(itemt);

    // 处理循环部分 {<加减运算符><项>}
    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)
{
    // 处理必须存在的 <因子>
    auto *factort = new treeNode("因子");
    tn->child.push_back(factort);
    factor(factort);

    // 处理循环部分 {<乘除运算符><因子>}
    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") {
        tn->child.push_back(new treeNode("标识符"));
        tn->child.back()->child.push_back(new treeNode(debugId));
        sym = GETSYM();
    }
    else if (sym == "number") {
        tn->child.push_back(new treeNode("无符号整数"));
        tn->child.back()->child.push_back(new treeNode(debugNum));
        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 error_exc(expression_in_factor_wrong);
    }
    else {
        error_exc(expression_in_factor_wrong);
    }
}

/*
<条件语句> ::= if<条件>then<语句>[else<语句>]
*/
void condition_sen(treeNode* tn)
{
    if (sym == "if") {
        tn->child.push_back(new treeNode("if"));
        sym = GETSYM();

        auto *conditiont = new treeNode("条件");
        tn->child.push_back(conditiont);
        condition(conditiont);

        if (sym == "then") {
            tn->child.push_back(new treeNode("then"));
            sym = GETSYM();

            auto *sen_BLOCKt = new treeNode("语句");
            tn->child.push_back(sen_BLOCKt);
            sen_BLOCK(sen_BLOCKt);

            // 处理可选的 else 部分
            if (sym == "else") {
                tn->child.push_back(new treeNode("else"));
                sym = GETSYM();

                auto *sen_BLOCKt2 = new treeNode("语句");
                tn->child.push_back(sen_BLOCKt2);
                sen_BLOCK(sen_BLOCKt2);
            }
        } else error_exc(if_then_wrong);
    }
}

/*
<条件> ::= <表达式><关系运算符><表达式>|odd<表达式>
<关系运算符> ::= =|<>|<|<=|>|>=
*/
void condition(treeNode* tn)
{
    if (sym != "odd") {
        auto *expressiont0 = new treeNode("表达式");
        tn->child.push_back(expressiont0);
        expression(expressiont0);
        if (sym == "=" || sym == "#" || sym == "<" || sym == "<=" || sym == ">" || sym == ">=") {
            string opr = sym;
            auto *idt = new treeNode(sym);
            tn->child.push_back(new treeNode("条件运算符"));
            tn->child.back()->child.push_back(idt);
            sym = GETSYM();
            auto *expressiont1 = new treeNode("表达式");
            tn->child.push_back(expressiont1);
            expression(expressiont1);

        } else error_exc(condition_wrong);         //不是正确的条件符
    }
    else {
        string opr = sym;
        tn->child.push_back(new treeNode("odd"));
        sym = GETSYM();
        auto *expressiont2 = new treeNode("表达式");
        tn->child.push_back(expressiont2);
        expression(expressiont2);
    }
}

/*
<过程调用语句> ::= call<标识符>
*/
void proc_call_sen(treeNode* tn)
{
    if (sym == "call") {
        tn->child.push_back(new treeNode("call"));
        sym = GETSYM();
        if (sym == "identifier") {
            auto *idt = new treeNode(debugId);
            tn->child.push_back(new treeNode("标识符"));
            tn->child.back()->child.push_back(idt);

            sym = GETSYM();
        }
        else error_exc(identifier_wrong);           //不是标识符
    } else return;
}

void do_while_sen(treeNode* tn)
{
    if (sym == "while") {
        tn->child.push_back(new treeNode("while"));
        sym = GETSYM();
        auto *conditiont = new treeNode("条件");
        tn->child.push_back(conditiont);
        condition(conditiont);
        if (sym == "do") {
            tn->child.push_back(new treeNode("do"));
            sym = GETSYM();
            auto *sen_BLOCKt = new treeNode("语句");
            tn->child.push_back(sen_BLOCKt);

            sen_BLOCK(sen_BLOCKt);

        } else error_exc(while_do_wrong);         //不是正确的while_do语句
    } else return;
}

/*
<读语句> ::= read'('<标识符>{,<标识符>}')'
*/
void read_sen(treeNode* tn)
{
    if (sym == "read") {
        tn->child.push_back(new treeNode("read"));

        sym = GETSYM();
        if (sym == "(") {
            tn->child.push_back(new treeNode("("));
            sym = GETSYM();
            if (sym == "identifier") {
                auto *idt = new treeNode(debugId);
                tn->child.push_back(new treeNode("标识符"));
                tn->child.back()->child.push_back(idt);

                sym = GETSYM();
            }
            else error_exc(identifier_wrong);       //不是标识符
            while (sym == ",") {
                tn->child.push_back(new treeNode(","));

                sym = GETSYM();
                if (sym == "identifier") {
                    auto *idt = new treeNode(debugId);
                    tn->child.push_back(new treeNode("标识符"));
                    tn->child.back()->child.push_back(idt);

                    sym = GETSYM();
                }
            }
            if (sym == ")") {
                tn->child.push_back(new treeNode(")"));
                sym = GETSYM();
            }
            else error_exc(read_end_wrong);       //不是正确的read语句结束
        } else error_exc(read_wrong);         //不是正确的read语句
    } else return;
}

/*
<写语句> ::= write'('<标识符>{,<标识符>}')'
*/
void write_sen(treeNode* tn)
{
    if (sym == "write") {
        tn->child.push_back(new treeNode("write"));
        sym = GETSYM();
        if (sym == "(") {
            tn->child.push_back(new treeNode("("));
            sym = GETSYM();
            auto *expressiont = new treeNode("表达式");
            tn->child.push_back(expressiont);
            expression(expressiont);

            while (sym == ",") {
                tn->child.push_back(new treeNode(","));
                sym = GETSYM();
                auto *expressionts = new treeNode("表达式");
                tn->child.push_back(expressionts);
                expression(expressionts);
            }
            if (sym == ")") {
                tn->child.push_back(new treeNode(")"));
                sym = GETSYM();
            }
            else error_exc(write_end_wrong);       //不是正确的write语句结束
        } else error_exc(write_wrong);         //不是正确的write语句
    } else return;
}

/*
<复合语句> ::= begin<语句>{;<语句>}end
*/
void complex_sen(treeNode* tn)
{
    if (sym == "begin") {
        tn->child.push_back(new treeNode("begin"));
        sym = GETSYM();
        auto *sen_BLOCKt = new treeNode("语句");
        tn->child.push_back(sen_BLOCKt);
        sen_BLOCK(sen_BLOCKt);
        while (sym == ";") {
            tn->child.push_back(new treeNode(";"));
            sym = GETSYM();
            auto *sen_BLOCKts = new treeNode("语句");
            tn->child.push_back(sen_BLOCKts);
            sen_BLOCK(sen_BLOCKts);
        }
        if (sym == "end") {
            tn->child.push_back(new treeNode("end"));
            sym = GETSYM();
        }
        else error_exc(complex_end_wrong);           //不是正确的复合语句结束
    } else return;
}

int main() {
    string fileinname;
    cin >> fileinname;
    streambuf *stdin_backup = cin.rdbuf();         //备份标准输入流
    fcin.open(fileinname);
    if (!fcin.is_open()) {
        cout << "failed to open " << fileinname << endl;
        return 0;
    }
    cin.rdbuf(fcin.rdbuf());                //将cin重定向到文件
    auto *BLOCKT = new treeNode("程序");
    while (fcin.tellg() != ios::end) {
        BLOCK(BLOCKT);
        if (sym == "finish" || sym == "error")
            break;
    }
    if (!error_grammar) {
        printTreeNode(BLOCKT, 0);
    }
    cin.rdbuf(stdin_backup);
    fcin.close();

    return 0;
}

文件 demo1.txt:

const a=1,b=2,c=3;
var v1,v2;

begin
    read(v1);
    v2:=v1+a+b+c;
    write(v2);
end.

文件 demo2.txt:

const c1=2;
var v1,v2,v3,v4;
procedure p1;
    var v5;
    begin
        v5:=2;
        write(v5/2+2-1);
        while v3#0 do
        begin
            v4:=v1/v2;
            v3:=v1-v4*v2;
            v1:=v2;
            v2:=v3;
        end;
    end;
procedure p2;
    const c2=2;
    procedure p3;
        begin
            if v1#1 then
            begin
                v1:=v1-1;
                v2:=v2*v1;
                call p3;
            end;
        end;
    begin
        call p3;
        if odd c2 then
            write(c2);
        if c2=2 then
            write(c2+1)
    end;
begin
    read(v1,v2);
    if v1<v2 then
    begin
        v3:=v1;
        v1:=v2;
        v2:=v3;
    end;
    begin;
        v3:=1;
        call p1;
        write(c1,c1*v1,c1*v1/2);
    end;
    read(v1);
    v2:=v1;
    call p2;
    write(v2);
end.

文件 demo3.txt:

const z=0;

var head,foot,cock,rabbit,n;

begin

    n := z;

    cock := 1;

    while cock <= head do

    begin

        rabbit :=head-cock;

        if cock*2+rabbit*4=foot then

        begin

            write(cock,rabbit);

            n:=n+1

        end;

        cock:=cock+1

    end;

    if n=0 then write(0,0)

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