编译原理实验:语法分析程序

这篇博客介绍了如何基于编译原理设计并实现一个语法分析程序,使用C++编程语言,针对文法规则进行递归子程序分析。实验要求包括按词法分析顺序输出单词信息,高亮显示特定语法成分,并为错误处理预留接口。文章还提到了输入输出文件格式、文法定义查看方式、评分标准和参考资料,提供了词法分析测试程序库以及源代码提交形式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 作者:lmx

编译原理语法解读及定义-C++文档类资源-优快云下载编译原理语法解读及定义更多下载资源、学习资料请访问优快云下载频道.https://download.youkuaiyun.com/download/weixin_48456383/85146396

编译原理语法分析实验包-C++文档类资源-优快云下载编译原理语法分析实验包更多下载资源、学习资料请访问优快云下载频道.https://download.youkuaiyun.com/download/weixin_48456383/85146339

【问题描述】

请根据给定的文法设计并实现语法分析程序,能基于上次作业的词法分析程序所识别出的单词,识别出各类语法成分。输入输出及处理要求如下:

(1)需按文法规则,用递归子程序法对文法中定义的所有种语法成分进行分析;

(2)为了方便进行自动评测,输入的被编译源文件统一命名为testfile.txt(注意不要写错文件名);输出的结果文件统一命名为output.txt(注意不要写错文件名);结果文件中包含如下两种信息:

    1)按词法分析识别单词的顺序,按行输出每个单词的信息(要求同词法分析作业,对于预读的情况不能输出)。

    2)在文法中高亮显示(见2020文法定义)的语法分析成分分析结束前,另起一行输出当前语法成分的名字,形如“<常量说明>”(注:未要求输出的语法成分仍需要分析)

【输入形式】testfile.txt中的符合文法要求的测试程序。

【输出形式】按如上要求将语法分析结果输出至output.txt中,中文字符的编码格式要求是UTF-8。

【特别提醒】(1)本次作业只考核对正确程序的处理,但需要为今后可能出现的错误情况预留接口。

                    (2)当前要求的输出只是为了便于评测,完成编译器中无需出现这些信息,请设计为方便打开/关闭这些输出的方案。

【文法定义】请到“2020年文法定义(用于查看文法,不计入成绩)”作业中查看文法 

【样例输入】

coNst int cONst1 = 001, const2 = -100;
const char const3 = '_';
int change1;
char change3;
int gets1(int var1,int var2){
    change1 = var1 + var2;
    return (change1);
}
void main(){
    printf("Hello World");
    printf(gets1(10, 20));
}

【样例输出】

CONSTTK coNst
INTTK int
IDENFR cONst1
ASSIGN =
INTCON 001
<无符号整数>
<整数>
COMMA ,
IDENFR const2
ASSIGN =
MINU -
INTCON 100
<无符号整数>
<整数>
<常量定义>
SEMICN ;
CONSTTK const
CHARTK char
IDENFR const3
ASSIGN =
CHARCON _
<常量定义>
SEMICN ;
<常量说明>
INTTK int
IDENFR change1
<变量定义无初始化>
<变量定义>
SEMICN ;
CHARTK char
IDENFR change3
<变量定义无初始化>
<变量定义>
SEMICN ;
<变量说明>
INTTK int
IDENFR gets1
<声明头部>
LPARENT (
INTTK int
IDENFR var1
COMMA ,
INTTK int
IDENFR var2
<参数表>
RPARENT )
LBRACE {
IDENFR change1
ASSIGN =
IDENFR var1
<因子>
<项>
PLUS +
IDENFR var2
<因子>
<项>
<表达式>
<赋值语句>
SEMICN ;
<语句>
RETURNTK return
LPARENT (
IDENFR change1
<因子>
<项>
<表达式>
RPARENT )
<返回语句>
SEMICN ;
<语句>
<语句列>
<复合语句>
RBRACE }
<有返回值函数定义>
VOIDTK void
MAINTK main
LPARENT (
RPARENT )
LBRACE {
PRINTFTK printf
LPARENT (
STRCON Hello World
<字符串>
RPARENT )
<写语句>
SEMICN ;
<语句>
PRINTFTK printf
LPARENT (
IDENFR gets1
LPARENT (
INTCON 10
<无符号整数>
<整数>
<因子>
<项>
<表达式>
COMMA ,
INTCON 20
<无符号整数>
<整数>
<因子>
<项>
<表达式>
<值参数表>
RPARENT )
<有返回值函数调用语句>
<因子>
<项>
<表达式>
RPARENT )
<写语句>
SEMICN ;
<语句>
<语句列>
<复合语句>
RBRACE }
<主函数>
<程序>

【评分标准】

按与预期结果不一致的行数扣分,每项扣5%。

【参考资料】

                   根据PASCAL-S文法的定义,阅读源代码,理解程序的框架,了解各语法成分对应的子程序以及子程序之间的调用关系和接口;对其中与实验作业文法中类似的语法成分,要重点阅读其代码,进行分析、理解,为今后的语义分析打下基础(详见

pascals-compiler.docx

【开发语言及环境】用C/C++实现,平台支持C++11标准,源代码文件必须使用UTF-8编码,才能够输出评测平台能够识别的中文(如果不确定源文件的编码,推荐使用notepad++查看)       

【辅助工具】

词法分析测试程序库.zip    

【提交形式】将所开发的语法分析程序的源文件(.cpp/.c/.h,不含工程文件)打包为zip或rar后提交(注意在MAC下压缩会产生额外的文件到压缩包中,需删掉额外文件后提交)

嗯,只会写递归下降,也不打算折磨自己写LL(1),LR(1)了

把之前的词法分析封装成头文件

Token.h

#ifndef __TOKEN_H__
#define __TOKEN_H__

#include <Token.h>
#include <algorithm>
#include <ctype.h>
#include <fstream>
#include <iostream>
#include <map>
#include <string.h>
#include <vector>
using namespace std;

class Token {
private:
    map<string, string> token;
    string filename;
    map<string, string> Category_code = {
        { "identifier", "IDENFR" }, { "else", "ELSETK" }, { "-", "MINU" }, { "=", "ASSIGN" },
        { "int_constant", "INTCON" }, { "switch", "SWITCHTK" }, { "*", "MULT" }, { ";", "SEMICN" },
        { "char_constant", "CHARCON" }, { "case", "CASETK" }, { "/", "DIV" }, { ",", "COMMA" },
        { "character_string", "STRCON" }, { "default", "DEFAULTTK" }, { "<", "LSS" }, { "(", "LPARENT" },
        { "const", "CONSTTK" }, { "while", "WHILETK" }, { "<=", "LEQ" }, { ")", "RPARENT" },
        { "int", "INTTK" }, { "for", "FORTK" }, { ">", "GRE" }, { "[", "LBRACK" },
        { "char", "CHARTK" }, { "scanf", "SCANFTK" }, { ">=", "GEQ" }, { "]", "RBRACK" },
        { "void", "VOIDTK" }, { "printf", "PRINTFTK" }, { "==", "EQL" }, { "{", "LBRACE" },
        { "main", "MAINTK" }, { "return", "RETURNTK" }, { "!=", "NEQ" }, { "}", "RBRACE" },
        { "if", "IFTK" }, { "+", "PLUS" }, { ":", "COLON" }
    };

public:
    //这里我称map中的键为下面的键,map中的值为下面的值,用来记录文件生成的键值
    //存放文件中对应的键
    vector<string> lexical_analysis_tokens;
    //存放文件中对应的键所对应的值
    vector<string> lexical_analysis_values;

    //构造函数
    Token()
    {
    }
    //构造函数
    ~Token()
    {
    }
    bool isdigit(char x) //判断数字
    {
        return x >= '0' && x <= '9';
    }
    bool isletter(char x) //判断字母
    {
        return (x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z');
    }
    string to_lower(string str) //大写转小写
    {
        int i = 0;

        while (str[i]) {
            if (str[i] > 'A' && str[i] < 'Z') {
                str[i] += 32;
            }
            i++;
        }
        return str;
    }
    // 词法分析
    string lexical_analysis(string filename)
    {
        //词法分析输出结果
        string out = "";
        // 类别码初始化
        fstream fin;
        fin.open(filename);
        if (!fin.is_open()) {
            cout << "Could not find the file\n";
            cout << "Program terminating\n";
            system("pause");
            exit(EXIT_FAILURE);
        }
        string temp = "\0";
        //每次读一行
        while (getline(fin, temp)) {

            // curr指针,初始指向0
            int curr = 0;
            // FDA状态
            int state = 0;
            //临时拼接字符串
            string temp_concat = "\0";
            while (curr < temp.length() || temp_concat != "\0") {
                switch (state) {
                case 0:
                    //去除非常见字符
                    if (temp[curr] - '\0' <= 32) {
                        // do nothing
                    }
                    //如果是字母或者是下划线进入状态1,标识符或者是基本类型
                    else if (isletter(temp[curr]) || temp[curr] == '_') {
                        state = 1;
                        temp_concat += temp[curr];

                    }
                    //如果是数字那么进入状态2,整形常量
                    else if (isdigit(temp[curr])) {
                        state = 2;
                        temp_concat += temp[curr];

                    } else {
                        string curr_char = "\0";
                        curr_char += temp[curr];
                        switch (temp[curr]) {
                        case '+':
                            out += Category_code[curr_char] + " " + temp[curr] + "\n";
                            lexical_analysis_tokens.push_back(Category_code[curr_char]);
                            lexical_analysis_values.push_back(string(1, temp[curr]));
                            break;
                        case '-':
                            out += Category_code[curr_char] + " " + temp[curr] + "\n";
                            lexical_analysis_tokens.push_back(Category_code[curr_char]);
                            lexical_analysis_values.push_back(string(1, temp[curr]));
                            break;
                        case '*':
                            out += Category_code[curr_char] + " " + temp[curr] + "\n";
                            lexical_analysis_tokens.push_back(Category_code[curr_char]);
                            lexical_analysis_values.push_back(string(1, temp[curr]));
                            break;
                        case '/':
                            out += Category_code[curr_char] + " " + temp[curr] + "\n";
                            lexical_analysis_tokens.push_back(Category_code[curr_char]);
                            lexical_analysis_values.push_back(string(1, temp[curr]));
                            break;
                        case ';':
                            out += Category_code[curr_char] + " " + temp[curr] + "\n";
                            lexical_analysis_tokens.push_back(Category_code[curr_char]);
                            lexical_analysis_values.push_back(string(1, temp[curr]));
                            break;
                        case ',':
                            out += Category_code[curr_char] + " " + temp[curr] + "\n";
                            lexical_analysis_tokens.push_back(Category_code[curr_char]);
                            lexical_analysis_values.push_back(string(1, temp[curr]));
                            break;
                        case '(':
                            out += Category_code[curr_char] + " " + temp[curr] + "\n";
                            lexical_analysis_tokens.push_back(Category_code[curr_char]);
                            lexical_analysis_values.push_back(string(1, temp[curr]));
                            break;
                        case ')':
                            out += Category_code[curr_char] + " " + temp[curr] + "\n";
                            lexical_analysis_tokens.push_back(Category_code[curr_char]);
                            lexical_analysis_values.push_back(string(1, temp[curr]));
                            break;
                        case '[':
                            out += Category_code[curr_char] + " " + temp[curr] + "\n";
                            lexical_analysis_tokens.push_back(Category_code[curr_char]);
                            lexical_analysis_values.push_back(string(1, temp[curr]));
                            break;
                        case ']':
                            out += Category_code[curr_char] + " " + temp[curr] + "\n";
                            lexical_analysis_tokens.push_back(Category_code[curr_char]);
                            lexical_analysis_values.push_back(string(1, temp[curr]));
                            break;
                        case '{':
                            out += Category_code[curr_char] + " " + temp[curr] + "\n";
                            lexical_analysis_tokens.push_back(Category_code[curr_char]);
                            lexical_analysis_values.push_back(string(1, temp[curr]));
                            break;
                        case '}':
                            out += Category_code[curr_char] + " " + temp[curr] + "\n";
                            lexical_analysis_tokens.push_back(Category_code[curr_char]);
                            lexical_analysis_values.push_back(string(1, temp[curr]));
                            break;
                        case ':':
                            out += Category_code[curr_char] + " " + temp[curr] + "\n";
                            lexical_analysis_tokens.push_back(Category_code[curr_char]);
                            lexical_analysis_values.push_back(string(1, temp[curr]));
                            break;

                        case '\'': // 表明字符常量
                            state = 3;
                            break;
                        case '"': // 表明字符串常量
                            state = 4;
                            break;
                        case '<': //<= ? <
                            state = 5;
                            break;
                        case '>': //>= ? >
                            state = 6;
                            break;
                        case '=': //== ? =
                            state = 7;
                            break;
                        case '!': //! ? !=
                            state = 8;
                            break;
                        default: //錯誤借口
                            state = -1;
                            break;
                        }
                    }
                    break;
                //标识符或者基本类型
                case 1:
                    //如果继续跟数字或字母继续拼接标识符或者基本类型
                    if (isalnum(temp[curr]) || temp[curr] == '_') {

                        temp_concat += temp[curr];
                        state = 1;
                    }
                    //否则标识符拼装完成
                    else {
                        //先去判断是不是基本类型,并清空拼接字符串,指针回退
                        if (Category_code.find(to_lower(temp_concat)) != Category_code.end()) {
                            out += Category_code[to_lower(temp_concat)] + " " + temp_concat + "\n";
                            lexical_analysis_tokens.push_back(Category_code[to_lower(temp_concat)]);
                            lexical_analysis_values.push_back(temp_concat);
                            temp_concat = "";
                            curr--;
                            state = 0;
                        }
                        // 否则就是标识符,刷新字符拼接,返回状态0
                        else {

                            out += Category_code["identifier"] + " " + temp_concat + "\n";
                            lexical_analysis_tokens.push_back(Category_code["identifier"]);
                            lexical_analysis_values.push_back(temp_concat);

                            state = 0;
                            temp_concat = "";
                            curr--;
                        }
                    }
                    break;
                //整型常量
                case 2:
                    //如果还是数字,继续拼接整形常量
                    if (isdigit(temp[curr])) {

                        temp_concat += temp[curr];
                        state = 2;
                    }
                    //否则整形常量拼接完成,指针回退,返回状态0
                    else {

                        out += Category_code["int_constant"] + " " + temp_concat + "\n";
                        lexical_analysis_tokens.push_back(Category_code["int_constant"]);
                        lexical_analysis_values.push_back(temp_concat);
                        state = 0;
                        temp_concat = "";
                        curr--;
                    }
                    break;
                // 字符常量
                case 3:
                    //如果没有碰到',继续拼接字符常量
                    if (temp[curr] != '\'') {

                        temp_concat += temp[curr];
                        state = 3;

                    }
                    //如果碰到',转回状态0,清空拼接字符串,但注意这里不需要回退指针
                    else {

                        out += Category_code["char_constant"] + " " + temp_concat + "\n";
                        lexical_analysis_tokens.push_back(Category_code["char_constant"]);
                        lexical_analysis_values.push_back(temp_concat);
                        state = 0;
                        temp_concat = "";
                    }
                    break;
                // 字符串常量
                case 4:
                    //如果没有碰到',继续拼接字符常量
                    if (temp[curr] != '"') {

                        temp_concat += temp[curr];
                        state = 4;

                    }
                    //如果碰到',转回状态0,清空拼接字符串,但注意这里不需要回退指针
                    else {

                        out += Category_code["character_string"] + " " + temp_concat + "\n";
                        lexical_analysis_tokens.push_back(Category_code["character_string"]);
                        lexical_analysis_values.push_back(temp_concat);
                        state = 0;
                        temp_concat = "";
                    }
                    break;

                //<= ? <
                case 5:
                    // <= 回退状态0
                    if (temp[curr] == '=') {
                        out += Category_code["<="] + " <=" + "\n";
                        lexical_analysis_tokens.push_back(Category_code["<="]);
                        lexical_analysis_values.push_back("<=");
                        state = 0;
                    }
                    //< 回退状态0,回退指针
                    else {
                        out += Category_code["<"] + " <" + "\n";
                        lexical_analysis_tokens.push_back(Category_code["<"]);
                        lexical_analysis_values.push_back("<");
                        state = 0;
                        curr--;
                    }
                    break;

                case 6:
                    // >= 回退状态0
                    if (temp[curr] == '=') {
                        out += Category_code[">="] + " >=" + "\n";
                        lexical_analysis_tokens.push_back(Category_code[">="]);
                        lexical_analysis_values.push_back(">=");
                        state = 0;
                    }
                    //> 回退状态0,回退指针
                    else {
                        out += Category_code[">"] + " >" + "\n";
                        lexical_analysis_tokens.push_back(Category_code[">"]);
                        lexical_analysis_values.push_back(">");
                        state = 0;
                        curr--;
                    }
                    break;

                case 7:
                    // == 回退状态0
                    if (temp[curr] == '=') {

                        out += Category_code["=="] + " ==" + "\n";
                        lexical_analysis_tokens.push_back(Category_code["=="]);
                        lexical_analysis_values.push_back("==");
                        state = 0;
                    }
                    //< 回退状态0,回退指针
                    else {
                        out += Category_code["="] + " =" + "\n";
                        lexical_analysis_tokens.push_back(Category_code["="]);
                        lexical_analysis_values.push_back("=");
                        state = 0;
                        curr--;
                    }
                    break;

                case 8:
                    // != 回退状态0
                    if (temp[curr] == '=') {

                        out += Category_code["!="] + " !=" + "\n";
                        lexical_analysis_tokens.push_back(Category_code["!="]);
                        lexical_analysis_values.push_back("!=");
                        state = 0;
                    }
                    //! 报错
                    else {
                        state = -1;
                    }
                    break;

                case -1:
                    cout << "wrong answer skip" << endl;
                    curr--;
                    break;
                }
                //移动指针
                curr++;
            }
        }

        out = "\0";
        for (int i = 0; i < lexical_analysis_tokens.size(); i++) {
            out += lexical_analysis_tokens[i] + " " + lexical_analysis_values[i] + "\n";
        }

        return out;
    }
    //读入验证文件,返回字符串
    string lexical_analysis_Verification(string filename)
    {

        string vout = "";
        fstream fin;
        fin.open(filename);
        if (!fin.is_open()) {
            cout << "Could not find the file\n";
            cout << "Program terminating\n";
            system("pause");
            exit(EXIT_FAILURE);
        }

        string tempout = "";
        while (getline(fin, tempout)) {
            vout += tempout + "\n";
        }
        return vout;
    }
    //输入需要验证的文件夹序号进行验证
    void lexical_analysis_Verificate(int number)
    {
        string out = "";
        for (int i = 1; i <= 10; i++) {
            string filename1 = "lexical_analysis\\" + to_string(number) + "\\testfile" + to_string(i) + ".txt";
            string filename2 = "lexical_analysis\\" + to_string(number) + "\\output" + to_string(i) + ".txt";
            string testout = lexical_analysis(filename1);
            string verificationout = lexical_analysis_Verification(filename2);
            out += ((verificationout == testout) ? "right" : "wrong");
            out += " ";
            lexical_analysis_tokens.clear();
            lexical_analysis_values.clear();
        }
        cout << out << endl;
    }
};

#endif //! TOKEN_H__

Grammar.h

#ifndef __GRAMMAR_H__
#define __GRAMMAR_H__
#include <Token.h>
#include <algorithm>
#include <ctype.h>
#include <fstream>
#include <iostream>
#include <map>
#include <string.h>
#include <utility>
#include <vector>
using namespace std;

class Grammar {

private:
public:
    //存放文件中对应的键
    vector<string> lexical_analysis_tokens;
    //存放文件中对应的键所对应的值
    vector<string> lexical_analysis_values;
    //语法分析结果
    vector<string> parsing_processing_tokens;
    vector<string> parsing_processing_values;

    //分辨有返回值还是无返回值的函数
    //(标识符,类型标识符)
    map<string, string> function_with_or_without_return_map;

    //指针
    int index = 0;

    Grammar() { }
    ~Grammar() { }
    Grammar(vector<string>& x, vector<string>& y)
    {
        lexical_analysis_tokens.assign(x.begin(), x.end());
        lexical_analysis_values.assign(y.begin(), y.end());
        index = 0;
    }

    void display()
    {
        for (int i = 0; i < parsing_processing_tokens.size(); i++) {
            cout << parsing_processing_tokens[i] << " " << parsing_processing_values[i] << " " << endl;
        }
    }
    //程序主入口 [<常量说明>][<变量说明>]{<有返回值函数定义>|<无返回值函数定义>}<主函数>
    void procedure()
    {
        // [<常量说明>]

        if (constant_description()) {
        }

        // [<变量说明>]
        if (variable_description()) {
        }

        // {<有返回值函数定义>|<无返回值函数定义>}
        while (index < lexical_analysis_tokens.size()) {
            if (function_definition_with_return_value() || function_definition_without_return_value()) {
            } else {

                break;
            }
        }

        // <主函数>
        if (main_function()) {
        }

        parsing_processing_tokens.push_back("<程序>");
        parsing_processing_values.push_back("\0");
    }

    // <主函数>    ::= void main‘(’‘)’ ‘{’<复合语句>‘}’
    bool main_function()
    {

        bool flag = false;
        if (lexical_analysis_tokens[index] == "VOIDTK") {
            parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
            parsing_processing_values.push_back(lexical_analysis_values[index]);
            index++;
            if (lexical_analysis_tokens[index] == "MAINTK") {
                parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
                parsing_processing_values.push_back(lexical_analysis_values[index]);
                index++;
                if (lexical_analysis_tokens[index] == "LPARENT") {
                    parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
                    parsing_processing_values.push_back(lexical_analysis_values[index]);
                    index++;
                    if (lexical_analysis_tokens[index] == "RPARENT") {
                        parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
                        parsing_processing_values.push_back(lexical_analysis_values[index]);
                        index++;
                        if (lexical_analysis_tokens[index] == "LBRACE") {
                            parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
                            parsing_processing_values.push_back(lexical_analysis_values[index]);
                            index++;

                            if (compound_statement()) {
                                if (lexical_analysis_tokens[index] == "RBRACE") {
                                    parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
                                    parsing_processing_values.push_back(lexical_analysis_values[index]);
                                    index++;
                                    parsing_processing_tokens.push_back("<主函数>");
                                    parsing_processing_values.push_back("\0");
                                    flag = true;
                                }
                            }
                        }
                    }
                }
            }
        }
        return flag;
    }

    // <无返回值函数定义>  ::= void<标识符>'('<参数表>')''{'<复合语句>'}'
    bool function_definition_without_return_value()
    {
        if (lexical_analysis_tokens[index] == "VOIDTK") {
            parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
            parsing_processing_values.push_back(lexical_analysis_values[index]);
            index++;
            if (lexical_analysis_tokens[index] == "IDENFR") {
                parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
                parsing_processing_values.push_back(lexical_analysis_values[index]);
                index++;

                if (lexical_analysis_tokens[index] == "LPARENT") {
                    //到这里一定是<无返回值函数定义>
                    function_with_or_without_return_map[lexical_analysis_values[index - 1]] = lexical_analysis_tokens[index - 2];
                    parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
                    parsing_processing_values.push_back(lexical_analysis_values[index]);
                    index++;
                    if (parameter_table()) {
                        if (lexical_analysis_tokens[index] == "RPARENT") {
                            parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
                            parsing_processing_values.push_back(lexical_analysis_values[index]);
                            index++;

                            if (lexical_analysis_tokens[index] == "LBRACE") {
                                parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
                                parsing_processing_values.push_back(lexical_analysis_values[index]);
                                index++;
                                if (compound_statement()) {
                                    if (lexical_analysis_tokens[index] == "RBRACE") {
                                        parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
                                        parsing_processing_values.push_back(lexical_analysis_values[index]);
                                        index++;
                                        parsing_processing_tokens.push_back("<无返回值函数定义>");
                                        parsing_processing_values.push_back("\0");
                                        return true;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            else {
                parsing_processing_tokens.pop_back();
                parsing_processing_values.pop_back();
                index--;
                return false;
            }
        }
        return false;
    }

    // <有返回值函数定义>  ::=  <声明头部>'('<参数表>')' '{'<复合语句>'}'
    bool function_definition_with_return_value()
    {
        if (declaration_header()) {

            if (lexical_analysis_tokens[index] == "LPARENT") {
                //到这里一定是<有返回值函数定义>
                function_with_or_without_return_map[lexical_analysis_values[index - 1]] = lexical_analysis_tokens[index - 2];
                parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
                parsing_processing_values.push_back(lexical_analysis_values[index]);
                index++;
                if (parameter_table()) {
                    if (lexical_analysis_tokens[index] == "RPARENT") {
                        parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
                        parsing_processing_values.push_back(lexical_analysis_values[index]);
                        index++;
                        if (lexical_analysis_tokens[index] == "LBRACE") {
                            parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
                            parsing_processing_values.push_back(lexical_analysis_values[index]);
                            index++;
                            if (compound_statement()) {

                                if (lexical_analysis_tokens[index] == "RBRACE") {
                                    parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
                                    parsing_processing_values.push_back(lexical_analysis_values[index]);
                                    index++;
                                    parsing_processing_tokens.push_back("<有返回值函数定义>");
                                    parsing_processing_values.push_back("\0");
                                    return true;
                                }
                            }
                        }
                    }
                }
            }
        }
        return false;
    }

    // <复合语句>   ::=  [<常量说明>][<变量说明>]<语句列>
    bool compound_statement()
    {

        // [<常量说明>]

        if (constant_description()) {
        }

        // [<变量说明>]
        if (variable_description()) {
        }
        // <语句列>
        if (statement_column()) {

            parsing_processing_tokens.push_back("<复合语句>");
            parsing_processing_values.push_back("\0");
            return true;
        }

        return false;
    }

    // <语句列>   ::= {<语句>}
    bool statement_column()
    {
        bool flag = false;
        while (index < lexical_analysis_tokens.size()) {
            if (sentence()) {

                flag = true;
                continue;
            } else {
                flag = true;
                break;
            }
        }
        if (flag == true) {
            parsing_processing_tokens.push_back("<语句列>");
            parsing_processing_values.push_back("\0");
        }
        return flag;
    }

    // <语句>    ::= <循环语句>|<条件语句>| <有返回值函数调用语句>;  |<无返回值函数调用语句>;|<赋值语句>;|<读语句>;|<写语句>;|<情况语句>|<空>;|<返回语句>; | '{'<语句列>'}'
    bool sentence()
    {

        bool flag = false;

        // <循环语句>
        if (circular_statement()) {

            flag = true;
        }

        //<条件语句>
        else if (conditional_statement()) {
            flag = true;
        }
        // 第一层筛查,判断函数名
        else if (function_with_or_without_return_map.find(lexical_analysis_values[index]) != function_with_or_without_return_map.end()) {
            //第二层筛查,判断是不是void类型
            if (function_with_or_without_return_map[lexical_analysis_values[index]] != "VOIDTK") {
                // <有返回值函数调用语句>;
                if (function_call_statement_with_return_value()) {
                    if (lexical_analysis_tokens[index] == "SEMICN") {
                        parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
                        parsing_processing_values.push_back(lexical_analysis_values[index]);
                        index++;
                        flag = true;
                    }
                }
            } else {
                if (function_call_statement_without_return_value()) {
                    if (lexical_analysis_tokens[index] == "SEMICN") {
                        parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
                        parsing_processing_values.push_back(lexical_analysis_values[index]);
                        index++;
                        flag = true;
                    }
                }
            }
        }

        // // <有返回值函数调用语句>;
        // else if (function_call_statement_with_return_value()) {
        //     if (lexical_analysis_tokens[index] == "SEMICN") {
        //         parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
        //         parsing_processing_values.push_back(lexical_analysis_values[index]);
        //         index++;
        //         flag = true;
        //     }
        // }

        // // <无返回值函数调用语句>;
        // else if (function_call_statement_without_return_value()) {
        //     if (lexical_analysis_tokens[index] == "SEMICN") {
        //         parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
        //         parsing_processing_values.push_back(lexical_analysis_values[index]);
        //         index++;
        //         flag = true;
        //     }
        // }

        //<赋值语句>;
        else if (assignment_statement()) {

            if (lexical_analysis_tokens[index] == "SEMICN") {

                parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
                parsing_processing_values.push_back(lexical_analysis_values[index]);
                index++;
                flag = true;
            }
        }

        //<读语句>;
        else if (read_statement()) {
            if (lexical_analysis_tokens[index] == "SEMICN") {
                parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
                parsing_processing_values.push_back(lexical_analysis_values[index]);
                index++;
                flag = true;
            }
        }

        //<写语句>
        else if (write_statement()) {

            if (lexical_analysis_tokens[index] == "SEMICN") {
                parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
                parsing_processing_values.push_back(lexical_analysis_values[index]);
                index++;
                flag = true;
            }
        }

        // <情况语句>
        else if (situation_statement()) {
            flag = true;
        }

        // <空>;
        else if (lexical_analysis_tokens[index] == "SEMICN") {
            parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
            parsing_processing_values.push_back(lexical_analysis_values[index]);
            index++;
            flag = true;
        }

        // <返回语句>;
        else if (return_statement()) {
            if (lexical_analysis_tokens[index] == "SEMICN") {
                parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
                parsing_processing_values.push_back(lexical_analysis_values[index]);
                index++;
                flag = true;
            }
        }

        //'{'<语句列>'}'
        else if (lexical_analysis_tokens[index] == "LBRACE") {
            parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
            parsing_processing_values.push_back(lexical_analysis_values[index]);
            index++;
            if (statement_column()) {
                if (lexical_analysis_tokens[index] == "RBRACE") {
                    parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
                    parsing_processing_values.push_back(lexical_analysis_values[index]);
                    index++;
                    flag = true;
                }
            } else {
                if (lexical_analysis_tokens[index] == "RBRACE") {
                    parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
                    parsing_processing_values.push_back(lexical_analysis_values[index]);
                    index++;
                    flag = true;
                }
            }
        } else {
            flag = false;
        }

        // else if(lexical_analysis_tokens[index] =="RBRACE")
        // {
        //     flag=false;
        // }

        if (flag == true) {
            parsing_processing_tokens.push_back("<语句>");
            parsing_processing_values.push_back("\0");
        }

        return flag;
    }
    // <返回语句>   ::=  return['('<表达式>')']
    bool return_statement()
    {
        if (lexical_analysis_tokens[index] == "RETURNTK") {
            parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
            parsing_processing_values.push_back(lexical_analysis_values[index]);
            index++;
            if (lexical_analysis_tokens[index] == "LPARENT") {
                parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
                parsing_processing_values.push_back(lexical_analysis_values[index]);
                index++;

                if (expression()) {
                    if (lexical_analysis_tokens[index] == "RPARENT") {
                        parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
                        parsing_processing_values.push_back(lexical_analysis_values[index]);
                        index++;
                    }
                }
            }
            parsing_processing_tokens.push_back("<返回语句>");
            parsing_processing_values.push_back("\0");
            return true;
        }
        return false;
    }

    // <情况语句>  ::=  switch ‘(’<表达式>‘)’ ‘{’<情况表><缺省>‘}’
    bool situation_statement()
    {
        bool flag = false;
        if (lexical_analysis_tokens[index] == "SWITCHTK") {
            parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
            parsing_processing_values.push_back(lexical_analysis_values[index]);
            index++;
            if (lexical_analysis_tokens[index] == "LPARENT") {
                parsing_processing_tokens.push_back(lexical_analysis_tokens[index]);
                parsing_processing_values.push_back(lexical_analysis_values[index]);
                index++;
                if (expression()) {
                    if (lexical_analysis_tokens[index] =&#
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值