精华内容
下载资源
问答
  • Python语言程序设计 Python程序语法元素分析 单元开篇 CC BY-NC-SA 4.0 嵩天 Python程序语法元素分析 - 程序的格式框架 - 命名与保留字 - 数据类型 - 语句与函数 - Python程序的输入输出 - "温度转换"代码分析 程序...
  • 自底向上分析语法分析程序设计与实现 一、实验任务及内容 编制一个文法的输入,从键盘、文件或文本框输入给定文法,依次存入输入缓冲区(字符型数据)。 编制一个算法,模拟LR(0)分析器的主控流程,实现对给定...

    自底向上分析语法分析程序设计与实现

    一、实验任务及内容

    1. 编制一个文法的输入,从键盘、文件或文本框输入给定文法,依次存入输入缓冲区(字符型数据)。
    2. 编制一个算法,模拟LR(0)分析器的主控流程,实现对给定文法的LR分析。最终生成LR(0)分析表。
    3. 编制程序运行时间控制程序,并作为函数在主控程序调用。

    二、实验环境

    Windows系统、C++

    三、实验的整个实现过程

    (1) 本实验使用的数据结构主要有map、set、数组。
    (2) 读入文件
    首先读入文法文件,将其中的文法存放在productions中,并加入“S’->S”。接着利用productions构造圆点只放置于产生式右部开头的位置的拓广文法,之后构造新状态时会用到该拓广文法中的产生式。
    (3) 构造项目集

    • 构造I_0状态
      使用产生式“S’->S”开始(本实验使用星号替代课本中的圆点),扫视能由*后的S能推出的产生式对应的项目,例如S->*A、S->*B。接下来分别以A、B等非终结符扫视,依次类推,直到I_0状态不再增加为止。
    • 构造所有的项目集
      以I_0为基本状态集,对于其中的每一个项目,如果圆点不是项目字符串最后的位置,则以圆点后面的字母作为输入符号,将其加入到新状态中,并将圆点向后移动。如果原点后是非终结符,则将该非终结符能推出的串加入到该新状态中。
      如果此新状态与状态集中的某个状态相同,则删除记录。
      在构造新状态时,记录各个状态之间的转换关系,存放到二维数组中,代表DFA图中的连线。
      (4) 构造Action表与GoTo表
      在这里插入图片描述

    根据DFA中记录的状态转换关系,可以很轻松的构造出Action表与GoTo表,使用二维数组存储。

    四、完整代码

    //!!!!!! 2020.11.26 QLU实验报告,QLUer勿抄袭!!!!!! 
    #include <iostream>
    #include <time.h>
    #include <fstream>
    #include <set>
    #include <map>
    using namespace std;
    ifstream input("wenfa.txt");
    map<string, set<string> > productions;//读入文件后,存放产生式
    map<string, set<string> > project;//在每个产生式右部前面加上点,得到初始项目集
    map<int, set<string> > StateSet;//状态
    map<int, set<string> > StateSetTemp;
    string css_by_order[20];
    string link[12][12];//存放各个状态之间的关系
    string ActionTable[20][20];
    int GoToTable[20][20];
    set<string> Vn;
    set<string> Vt;
    string vn_index[10];
    string vt_index[10];
    
    bool isVn(char ch) {
        if (ch >= 'A' && ch <= 'Z') {
            return true;
        } else{
            return false;
        }
    }
    
    //得到最初项目集
    void getProject() {
        productions["S\'"].insert("S");
        //读入文法文件
        int k = 1;
        string temp;
        while (getline(input, temp)) {
            productions[temp.substr(0,1)].insert(temp.substr(3, temp.length() - 3 +1));
            css_by_order[k++] = temp;
        }
        //构造基本项目集,即圆点位于右部开头的位置
        string dot = "*";
        for(map<string, set<string>>::iterator it = productions.begin(); it != productions.end(); it++) {
            for(set<string>::iterator ij =it->second.begin(); ij != it->second.end(); ij++) {
                string startStr = *ij;
                startStr.insert(0, dot, 0, 1);
                project[it->first].insert(startStr);
            }
        }
    }
    
    void Init_I0() {
        StateSet[0].insert("S'->*S");
        //先将所有的左部为S的产生式加入0号状态中
        for(map<string, set<string> >::iterator it = project.begin(); it != project.end(); it++) {
            if ((it->first) == "S") {
                for(set<string>::iterator ij = it->second.begin(); ij != it->second.end(); ij++) {
                    StateSetTemp[0].insert(it->first + "->" + *ij);
                }
            }
        }
        //根据I0状态中已知内容,添加后续
        while (! StateSetTemp[0].empty()){
            set<string>::iterator it = StateSetTemp[0].begin();
            string it_str = *it;//暂时集合中的每一条产生式
            //如果点后面是非终结符,在project例找到它能推出来的产生式,加入temp,
            if (isVn(it_str[4])) {
                string after_dot_ch = it_str.substr(4,1);
                for(set<string>::iterator css = project[after_dot_ch].begin(); css != project[after_dot_ch].end(); css++) {
                    StateSetTemp[0].insert(after_dot_ch + "->" + *css);
                }
                StateSetTemp[0].erase(it_str);
                StateSet[0].insert(it_str);
            }else if(! isVn(it_str[4])) {
                StateSetTemp[0].erase(it_str);
                StateSet[0].insert(it_str);
            }
        }
    }
    
    string MoveDot(string s, int pos) {
        s.erase(pos,1);
        s = s.substr(0, pos+1) + "*" + s.substr(pos+1, s.length()-pos);
        return s;
    }
    
    void GenerateState() {
        Init_I0();
        int i = 0;
        int state_num = 0;
        string enter;
        //对于每一个状态
        while (i < StateSet.size()) {
            map<string, set<string>> after_dot_ch;
            //构造该状态中的after_dot_ch的map,first为点后面的字母,即输入字母,second为输入字母为first时的项目
            for (set<string>::iterator it = StateSet[i].begin(); it != StateSet[i].end(); it++) {//对于此状态的每一个项目
                int dot_pos = (*it).find("*");
                if (dot_pos + 1 != (*it).length()) {
                    string s = (*it).substr(dot_pos + 1, 1);//点后面的字母
                    after_dot_ch[s].insert(*it);
                }
            }
            if (after_dot_ch.size() == 0) {
                i++;
                continue;
            }
            for (map<string, set<string>>::iterator adc = after_dot_ch.begin(); adc != after_dot_ch.end(); adc++) {
                enter = adc->first;
                state_num++;
                for (set<string>::iterator p = adc->second.begin(); p != adc->second.end(); p++) {
                    int dot_pos = (*p).find("*");
                    string moved_proj = MoveDot(*p, dot_pos);
                    int moved_dot_pos = (moved_proj).find("*");
                    StateSet[state_num].insert(moved_proj);
    
                    string moved_adc = moved_proj.substr(moved_dot_pos + 1, 1);
                    if (isVn(moved_adc[0])) {
                        //如果点移动后的字符串中,点后字母是非终结符,则将以该非终结符开头的project加入该状态
                        for (set<string>::iterator proj_css = project[moved_adc].begin();
                             proj_css != project[moved_adc].end(); proj_css++) {
                            StateSet[state_num].insert(moved_adc + "->" + (*proj_css));
                        }
                    }
                }
                    //--------判断之前是否有与新产生的状态相等的--------
                    bool is_equal = false;
                    for (int j = 0; j < state_num; ++j) {
                        if (StateSet[state_num].size() == StateSet[j].size()) {
                            for (set<string>::iterator str = StateSet[j].begin(); str != StateSet[j].end(); str++) {
                                if (StateSet[state_num].count(*str) == 0){
                                    break;
                                } else{
                                    link[i][j] = enter;
                                    is_equal = true;
                                }
                            }
                        }
                    }
                    if (is_equal == true) {//两个状态全部项目都相等
                        StateSet.erase(state_num);
                        state_num--;
                    } else{
                        link[i][state_num] = enter;
                    }
                    //--------------------------------------------
            }
            i++;
        }
    }
    
    void printState() {
        cout << "-------------------------Status--------------------------"<<endl;
        for(map<int, set<string>>::iterator it = StateSet.begin(); it != StateSet.end(); it++) {
            cout << "I_" << it->first << ": ";
            for(set<string>::iterator ij = it->second.begin(); ij != it->second.end(); ij++) {
                cout << *ij << ", ";
            }
            cout << endl;
        }
        cout << "---------------------------------------------------------"<<endl;
    }
    
    void printLinkedTable() {
        cout << "============================================DFA================================================"<<endl;
        cout <<  '\t';
        for (int i = 0; i < 11; ++i) {
            cout << i << '\t';
        }
        cout << endl;
        for (int i = 0; i < 11; ++i) {
            cout << i << '\t';
            for (int j = 0; j < 11; ++j) {
                    cout << link[i][j] << '\t';
            }
            cout << endl;
        }
    }
    
    void getVnandVt() {
        for(map<string, set<string>>::iterator it = productions.begin(); it != productions.end(); it++) {
            string c = it->first;
            if (c != "S'")
                Vn.insert(c);
            for(set<string>::iterator ij = it->second.begin(); ij != it->second.end(); ij++) {
                for (int i = 0; i < (*ij).length(); ++i) {
                    if (!isVn((*ij)[i])) {
                        Vt.insert((*ij).substr(i, 1));
                    }
                }
            }
        }
        Vt.insert("#");
    }
    
    int findIndex(string enter) {
        int pos;
        if (!isVn(enter[0])) {
            for (int k = 0; k < 10; ++k) {
                if (vt_index[k] == enter) {
                    pos = k;
                    break;
                }
            }
        } else{
            for (int k = 0; k < 10; ++k) {
                if (vn_index[k] == enter) {
                    pos = k;
                    break;
                }
            }
        }
        return pos;
    }
    
    void GenerateAction_Table() {
        //构造Action分析表的行名与列名
        ActionTable[0][0] = "";
        int j = 0;
        set<string>::iterator ij = Vt.begin();
        while (j < Vt.size()) {
            vt_index[j] = *ij;
            ij++; j++;
        }
    
        //构造Action表
        // ---------移入
        for (int i = 0; i < StateSet.size(); ++i) {
            for (int j = 0; j < StateSet.size(); ++j) {
                if (link[i][j].length() != 0 && (!isVn(link[i][j][0]))) {
                    string enter = link[i][j];
                    int pos = findIndex(enter);
                    ActionTable[i][pos] = "s" + to_string(j);
                }
            }
        }
        // ---------规约
        for (int l = 0; l < StateSet.size(); ++l) {
            if (StateSet[l].size() == 1) {
                set<string>::iterator it = StateSet[l].begin();
                string proj = *it;
                if (proj == "S'->S*") {
                    ActionTable[l][findIndex("#")] = "acc";
                    continue;
                }
                int dot_pos = proj.find("*");
                if (dot_pos+1 == proj.length()) {
                    string no_dot_proj = proj.erase(dot_pos,1);
                    //先找到这个项目对应的无点产生式index
                    int index = 0;//无点产生式的编号index。第几条产生式
                    for (index = 0; index < 20; ++index) {
                        if (css_by_order[index] == no_dot_proj) {
                            break;
                        }
                    }
                    for (int m = 0; m < Vt.size(); ++m) {
                        ActionTable[l][m] = "r" + to_string(index);
                    }
                }
            }
        }
        cout << endl;
        cout << endl;
        cout << "----------------------[Action]---------------------" << endl;
        int m = 0;
        cout << '\t';
        while (vt_index[m].length() != 0) {
            cout << vt_index[m] << '\t';
            m++;
        }
        cout << endl;
        for (int k = 0; k < StateSet.size(); ++k) {
            cout << k << '\t';
            for (int l = 0; l < Vt.size(); ++l) {
                cout << ActionTable[k][l] << '\t';
            }
            cout <<endl;
        }
    }
    
    void GenerateGoTo_Table() {
        int i = 0;
        set<string>::iterator it = Vn.begin();
        while (i < Vn.size()) {
            vn_index[i] = *it;
            it++; i++;
        }
    
        //构造GoTo表
        //在link表中遍历
        for (int i = 0; i < StateSet.size(); ++i) {
            for (int j = 0; j < StateSet.size(); ++j) {
                if ( link[i][j].length() != 0 && isVn(link[i][j][0]) ) {
                    string enter = link[i][j];
                    int pos = findIndex(enter);
                    GoToTable[i][pos] = j;
                }
            }
        }
        cout << endl;
        cout << endl;
        cout << "----------------------[GoTo]---------------------" << endl;
        int m = 0;
        cout << '\t';
        while (vn_index[m].length() != 0) {
            cout << vn_index[m] << '\t';
            m++;
        }
        cout << endl;
        for (int k = 0; k < StateSet.size(); ++k) {
            cout << k << '\t';
            for (int l = 0; l < Vn.size(); ++l) {
                if (GoToTable[k][l] != 0)
                    cout << GoToTable[k][l] << '\t';
                else
                    cout << '\t';
            }
            cout << endl;
        }
    }
    
    int main() {
        clock_t start,end;//定义clock_t变量
        start = clock(); //开始时间
    
        getProject();
        GenerateState();
        printState();
        printLinkedTable();
        getVnandVt();
        GenerateAction_Table();
        GenerateGoTo_Table();
    
        //输出时间
        end = clock();   //结束时间
        cout << endl;
        double times = double(end-start)/CLOCKS_PER_SEC;
        cout<<"The Run time = "<<times<<"s" << " = " <<times * 1000 <<"ms" << endl;
        return 0;
    }
    
    

    四、实验结果

    实验用例:以文本文件与C++程序放在同一目录下

    S->A
    S->B
    A->aAb
    A->c
    B->aBb
    B->d
    

    实验结果图

    展开全文
  • 计算机专业编译原理课程的词法、语法分析程序设计源代码。
  • 语法分析是编译过程的核心部分,其基本任务是根据语言的语法规则进行语法分析,如果不存在语法错误即给出正确的语法结果,并为语义分析和代码生成做准备。”
  • 编译原理实验二:赋值语句的语法分析程序设计 1.1实验内容 目的: 在前面实验的基础上,通过设计、编制、调试一个典型的赋值语句的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查,进一步掌握常用...

    编译原理实验二:赋值语句的语法分析程序设计

    1.1实验内容

    目的:

    • 在前面实验的基础上,通过设计、编制、调试一个典型的赋值语句的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查,进一步掌握常用的语法分析方法。

    要求:

    • 设计出给定源语言中包含有算术表达式、关系表达式和逻辑表达式的赋值语句的文法,文法满足采用的语法分析方法的要求。
    • 选择最有代表性的语法分析方法,如算符优先法(或简单优先法)、递归下降分析法、LL分析法和LR分析法之一进行语法分析。
    • 选择对各种常见程序语言都通用的语法结构,以文本文件形式输入源程序,把其中赋值语句作为分析对象进行语法检查,输出分析结果。

    1.2实验分析

    在本次的实验中呢,我采用的方法是递归下降法*(别问,问就是相对简单)*其实也还好,看各自感觉吧,然后我使用的语法是PL/0相关赋值语句的语法,如下:

    〈赋值语句〉∷=〈标志符〉:=〈表达式〉
    〈表达式〉∷= [+|-]〈项〉{〈加法运算符〉〈项〉}
    〈项〉∷= 〈因子〉{〈乘法运算符〉〈因子〉}
    〈因子〉∷= 〈标志符〉|〈无符号整数〉|‘(’〈表达式〉‘)’

    特别巧的是,由于本人的学术不精,刚开始并不知道递归下降法还需要求出相应的字符的select集,而且我使用的语法刚好是不需要往后看一个字符就可以完成的,所以,在验收的时候我才被老师说明白需要求出每个产生式的select,如果有需要参考我的代码的童鞋们可以自己加一下相关的部分哦,不是特别难。

    递归下降法在我看来相对于其他几种方法都比较简单,是对每一个产生式进行分析,不同产生式对应的函数之间进行调用等,便可完成相应的功能。

    1.3实验代码

    赋值语句相应产生式的分析:

    void assignment() {
    	if (s == "ident") {
    		flag = move();
    		if (flag == 0) {
    			cout << "语法错误 标识符后面缺项" << endl;
    			success = 0;
    			return;
    		}
    		if (s == "becomes") {
    			flag = move();
    			if (flag == 0) {
    				cout << "语法错误 赋值符后面缺项" << endl;
    				success = 0;
    				return;
    			}
    			expression();
    		}
    		else {
    			cout << "赋值语句中标识符后面缺少赋值符号" << endl;
    			success = 0;
    			return;
    		}
    	}
    	else {
    		cout << "赋值语句分析错误!" << endl;
    		success = 0;
    		return;
    	}
    }
    

    表达式相应产生式的分析:

    void expression() {
    	if ((s == "plus") || (s == "minus")) {
    		flag = move();
    		if (flag == 0) {
    			cout << "语法错误 加法运算符后面缺项" << endl;
    			success = 0;
    			return;
    		}
    	}
    	item();
    	if (!success) {
    		return;
    	}
    	while ((s == "plus") || (s == "minus")) {
    		flag = move();
    		if (flag == 0) {
    			cout << "语法错误 加法运算符后缺项" << endl;
    			success = 0;
    			return;
    		}
    		item();
    		if (!success) {
    			return;
    		}
    	}
    }
    

    项相应产生式的分析:

    void item() {
    	factor();
    	if (!success) {
    		return;
    	}
    	while ((s == "mul") || (s == "div")) {
    		flag = move();
    		if (flag == 0) {
    			cout << "语法错误 乘法运算符后缺因子" << endl;
    			success = 0;
    			return;
    		}
    		factor();
    		if (!success) {
    			return;
    		}
    	}
    }
    

    因子相应产生式的分析:

    void factor() {
    	int lpnum = 0;
    	if ((s == "ident") || (s == "number")) {
    		flag = move();
    		if (lpnum == 0 && s == "rparen") {
    			cout << "语法错误 括号不匹配问题" << endl;
    			success = 0;
    			return;
    		}
    	}
    	else if (s == "lparen") {
    		lpnum++;
    		flag = move();
    		if (flag == 0) {
    			cout << "语法错误 左括号后缺表达式" << endl;
    			success = 0;
    			return;
    		}
    		expression();
    		if (!success) {
    			return;
    		}
    		if (flag == 0 || s != "rparen") {
    			cout << "语法错误 表达式后面缺少右括号" << endl;
    			success = 0;
    			return;
    		}
    		else {
    			lpnum--;
    			flag = move();
    			if (flag == 0) {
    				return;
    			}
    		}
    	}
    	else {
    		cout << "语法错误 因子分析错误" << endl;
    		success = 0;
    		return;
    	}
    }
    

    以上就是本次实验中主要的实现内容了,如果有不妥的地方希望大家帮忙指出哦,我们一起进步呀!

    展开全文
  • 实验目的】 练习构造递归下降语法分析程序的方法,熟悉上下文无关文法... 利用某一高级程序设计语言构造语法分析程序 【具体要求】对于给定的文法G[E] E-&gt;TE’ E’-&gt;+TE’ | ε T-&gt;F...

    实验目的】

           练习构造递归下降语法分析程序的方法,熟悉上下文无关文法的使用,加深对课堂教学的理解;提高语法分析方法的实践能力

    【实验要求】

        利用某一高级程序设计语言构造语法分析程序  

    【具体要求】对于给定的文法G[E]

                  E->TE’

                 E’->+TE’ | ε

                T->FT’

                T’->*F T’| ε

                F->(E) | i

         采用递归下降语法分析法编写语法分析程序,该语法分析程序判断输入的字符串是否符合上述文法,并能够输出相应的结果(是语法成分或不是语法成分)。

     

     

    上面一版有个bug当输入 i)会提示正确

    下面做了修改, 第29-35行,可能还有其他错误,欢迎留言。

    /*
        实验名称:实验3  递归下降语法分析程序设计
        学号:
        姓名:niu91(859222829)
        班级:
    */
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    char str[10];
    int index = 0;
    void E();  // E->TX;
    void X();  // X->+TX | e
    void T();  // T->FY
    void Y();  // Y->*FY | e
    void F();  // F->(E) | i
    int main() {
        int len;
        int m;
        printf("请输入要测试的次数:");
        scanf("%d", &m);
        while (m--) {
            printf("请输入算数表达式:");
            scanf("%s", str);
            len = strlen(str);
            str[len] = '#';
            str[len + 1] = '\0';
            E();
            //<< 2020年12月15日 fixbug:: i)
            if (str[index] == '#')
                printf("正确语句!\n");
            else {
                printf("分析失败!\n");
            }
            //>>
    
            strcpy(str, "");
            index = 0;
        }
        return 0;
    }
    void E() {
        T();
        X();
    }
    void X() {
        if (str[index] == '+') {
            index++;
            T();
            X();
        }
    }
    void T() {
        F();
        Y();
    }
    void Y() {
        if (str[index] == '*') {
            index++;
            F();
            Y();
        }
    }
    void F() {
        if (str[index] == 'i') {
            index++;
        } else if (str[index] == '(') {
            index++;
            E();
            if (str[index] == ')') {
                index++;
            } else {
                printf("分析失败!\n");
                exit(0);
            }
        } else {
            printf("分析失败!\n");
            exit(0);
        }
    }

     

    展开全文
  • SyntaxAnalyzerjava实现的语法分析器及词法分析器一、实验目的设计、编写一个语法分析程序,加深对语法分析原理的理解。二、实验原理语法分析器是在词法分析之后,根据词法分析的结果和定义的语法规则判断输入的程序...

    SyntaxAnalyzer

    java实现的语法分析器及词法分析器

    一、实验目的

    设计、编写一个语法分析程序,加深对语法分析原理的理解。

    二、实验原理

    语法分析器是在词法分析之后,根据词法分析的结果和定义的语法规则判断输入的程序是否有语法错误,LL(1)分析是使用显式栈而不是递归调用来完成分析。以标准方式表示这个栈非常有用,这样LL(1)分析程序的动作就可以快捷地显现出来。LL(1)的含义是:第一个L表明自顶向下分析是从左向右扫描输入串,第2个L表明分析过程中将使用最左推导,1表明只需向右看一个符号便可决定如何推导,即选择哪个产生式(规则)进行推导。

    三、实验内容

    (1)程序利用Java语言,给出其词法的产生式。希望这个语言中包含数学运算表达式,赋值,函数调用,控制流语句(分支或循环),类型声明等基本元素。

    (2)本实验设计的是基于LL(1) 分析的语法分析器,并用程序实现了对所写语言的LL(1) 分析测试。

    四、实验方法

    (1)定义文法语言,将文法用产生式表示。

    (2)提取公共左因子,消除左递归。

    (3)求FIRST和FOLLOW集。

    (4)构造LL(1)预测分析表。

    (5)根据分析表编写程序,测试程序。

    五、实验设计

    1.定义语法分析使用的文法语言:

    ::= | Ɛ;

    ::= | | |

    | | Ɛ

    ::= ;

    ::= = ;

    ::= ( );

    ::= if ( ) { }

    ::= else{ } | Ɛ

    ::= while ( ) { }

    ::= | ,

    ::=

    ::= > | >= | < | <= | != | ==

    ::= char | short | int | long | float | double

    ::= +T | -T | T | + T | -T

    T ::= F | T*F | T/F

    F ::= | | ()

    2.将上述文法用产生式表示:

    其中,S’:程序(语句的组合),S:语句,Q:else语句,L:标识符表,E:表达式,X:条件表达式,R:比较运算符,id:标识符,num:常量

    S’ → S S’| Ɛ

    S → A L; | id=E; | id(L); | if(X){S}Q | while(X){S} | Ɛ

    A → char | short | int | long | float | double

    Q → else{S} | Ɛ

    L → id | L , id

    X → ERE

    R → > | >= | < | <= | == | !=

    E → +T | -T | T | E+T | E-T

    T → F | T*F | T/F

    F → id | num | (E)

    3.提取公共左因子:

    S’ → S S’| Ɛ

    S → A L; | id B | if(X){S}Q | while(X){S} | Ɛ

    A → char | short | int | long | float | double

    B → (L); | =E;

    L → id | L , id

    Q → else{S} | Ɛ

    X → ERE

    R → > | >= | < | <= | == | !=

    E → +T | -T | T | EM

    M → +T | -T

    T → F | TN

    N → *F |/F

    F → id | num | (E)

    4.消除左递归:

    S’ → S S’

    S’ → Ɛ

    S → A L;

    S → id B

    S → if(X){S}Q

    S → while(X){S}

    S → Ɛ

    B → (L);

    B → =E;

    L → id L’

    L’→ , id L’

    L’→ Ɛ

    Q → else{S}

    Q → Ɛ

    X → ERE

    E → TE’

    E → +TE’

    E → -TE’

    E’ → ME’

    E’ → Ɛ

    M → +T

    M → -T

    T → FT’

    T’ → NT’

    T’ → Ɛ

    N → *F

    N → /F

    F → id

    F → num

    F → (E)

    R → >

    R → >=

    R → <

    R → <=

    R → ==

    R → !=

    A → char

    A → short

    A → int

    A → long

    A → float

    A → double

    5.求FIRST集:

    First(S’)={ char , short , int , long , float , double , id , if , while , Ɛ }

    First(S)={ char , short , int , long , float , double , id , if , while , Ɛ }

    First(A)={ char , short , int , long , float , double }

    First(B)={ ( , = }

    First(L)={ id }

    First(L’)={ ,, Ɛ }

    First(Q)={ else , Ɛ }

    First(X)={ + , - , id , num , ( }

    First(R)={ > , >= , < , <= , != , == }

    First(E)={ + , - , id , num , ( }

    First(E’)={ + , - , Ɛ }

    First(M)={ + , - }

    First(T)={ id , num , ( }

    First(T’)={ * , / , Ɛ }

    First(N)={ * , / }

    First(F)={ id , num , ( }

    6.求FOLLOW集:

    Follow (S’)={ $ }

    Follow (S)={ $ , } }

    Follow (B)={ $ , } }

    Follow (L)={ $ , ) , ; , } }

    Follow (L’)={ $ , ) , ; , } }

    Follow (Q)={ $ , } }

    Follow (X)={ ) }

    Follow (R)={ + , - , id , num , ( }

    Follow (E)={ ) , ; , > , >= , < , <= , != , == }

    Follow (E’)={ ) , ; , > , >= , < , <= , != , == }

    Follow (M)={ ) , ; , > , >= , < , <= , != , == , + , - }

    Follow (T)={ ) , ; , > , >= , < , <= , != , == , + , - }

    Follow (T’)={ ) , ; , > , >= , < , <= , != , == , + , - }

    Follow (N)={ ) , ; , > , >= , < , <= , != , == , + , - , * , / }

    Follow (F)={ ) , ; , > , >= , < , <= , != , == , + , - , * , / }

    7.构造LL(1)的预测分析表:

    43542f941d0727f565c7cf65b7d77826.png

    LL(1)预测分析表中的数字分别代表的产生式如下:

    0:S → A L;

    1:S → id B

    2:S → if(X){P}Q

    3:S → while(X){P}

    4:S → Ɛ

    5:B → (L);

    6:B → =E;

    7:L → id L’

    8:L’→ ,id L’

    9:L’→ Ɛ

    10:Q → else{S}

    11:Q → Ɛ

    12:X → ERE

    13:E → +TE’

    14:E → -TE’

    15:E → TE’

    16:E’→ ME’

    17:E’→ Ɛ

    18:M → +T

    19:M → -T

    20:T → FT’

    21:T’→ NT’

    22:T’→ Ɛ

    23:N → *F

    24:N → /F

    25:F → id

    26:F → num

    27:F → (E)

    28:R → >

    29:R → >=

    30:R → <

    31:R → <=

    32:R → ==

    33:R → !=

    34:S’ → S S’

    35:S’ → Ɛ

    36:A → char

    37:A → short

    38:A → int

    39:A → long

    40:A → float

    41:A → double

    六、数据结构

    (1)使用ArrayList来存储当前栈的内容

    (2)使用ArrayList来存储待读队列的内容,Integer此处为单词的种别码,用于表示词法分析器的分析结果。

    自定义类Production,产生式类,包含String类型的完整产生式、String类型的产生式左侧符号、String[]类型的产生式右侧符号。(此处左右是相对于产生式中的→而言的)。

    七、实现代码

    语法分析器接收词法分析器的结果作为输入,即输入为单词种别码和相应的单词的序列。

    例如:(种别码和单词间的逗号仅表示分隔)

    e79c041056803c3c7c06c60b382cd093.png

    1.初始化

    首先定义了五个全局变量:

    private static ArrayList stack = new ArrayList<>(); // 当前栈

    private static ArrayList reader = new ArrayList<>(); // 待读队列

    private static Production[] productions = new Production[42]; // 产生式数组

    private static HashMap map_i2s; // 种别码Map,种别码为键,单词为值

    private static HashMap map_s2i; // 种别码Map,单词为键,种别码为值

    初始化种别码Map,要和词法分析器内单词对应的种别码相同:

    private static void initMap() {

    map_s2i = new HashMap<>();

    map_s2i.put("char", 1);

    map_s2i.put("short", 2);

    map_s2i.put("int", 3);

    map_s2i.put("long", 4);

    map_s2i.put("float", 5);

    map_s2i.put("double", 6);

    map_s2i.put("final", 7);

    map_s2i.put("static", 8);

    map_s2i.put("if", 9);

    map_s2i.put("else", 10);

    map_s2i.put("while", 11);

    map_s2i.put("do", 12);

    map_s2i.put("for", 13);

    map_s2i.put("break", 14);

    map_s2i.put("continue", 15);

    map_s2i.put("void", 16);

    map_s2i.put("id", 20);

    map_s2i.put("num", 30);

    map_s2i.put("=", 31);

    map_s2i.put("==", 32);

    map_s2i.put(">", 33);

    map_s2i.put("

    map_s2i.put(">=", 35);

    map_s2i.put("<=", 36);

    map_s2i.put("+", 37);

    map_s2i.put("-", 38);

    map_s2i.put("*", 39);

    map_s2i.put("/", 40);

    map_s2i.put("(", 41);

    map_s2i.put(")", 42);

    map_s2i.put("[", 43);

    map_s2i.put("]", 44);

    map_s2i.put("{", 45);

    map_s2i.put("}", 46);

    map_s2i.put(",", 47);

    map_s2i.put(":", 48);

    map_s2i.put(";", 49);

    map_s2i.put("!=", 50);

    map_s2i.put("$", 60);

    map_i2s = new HashMap<>();

    map_i2s.put(1, "char");

    map_i2s.put(2, "short");

    map_i2s.put(3, "int");

    map_i2s.put(4, "long");

    map_i2s.put(5, "float");

    map_i2s.put(6, "double");

    map_i2s.put(7, "final");

    map_i2s.put(8, "static");

    map_i2s.put(9, "if");

    map_i2s.put(10, "else");

    map_i2s.put(11, "while");

    map_i2s.put(12, "do");

    map_i2s.put(13, "for");

    map_i2s.put(14, "break");

    map_i2s.put(15, "continue");

    map_i2s.put(16, "void");

    map_i2s.put(20, "id");

    map_i2s.put(30, "num");

    map_i2s.put(31, "=");

    map_i2s.put(32, "==");

    map_i2s.put(33, ">");

    map_i2s.put(34, "

    map_i2s.put(35, ">=");

    map_i2s.put(36, "<=");

    map_i2s.put(37, "+");

    map_i2s.put(38, "-");

    map_i2s.put(39, "*");

    map_i2s.put(40, "/");

    map_i2s.put(41, "(");

    map_i2s.put(42, ")");

    map_i2s.put(43, "[");

    map_i2s.put(44, "]");

    map_i2s.put(45, "{");

    map_i2s.put(46, "}");

    map_i2s.put(47, ",");

    map_i2s.put(48, ":");

    map_i2s.put(49, ";");

    map_i2s.put(50, "!=");

    map_i2s.put(60, "$");

    }

    初始化产生式:规则自己定义

    /**

    * 产生式类

    */

    private static class Production {

    String l_str;

    String[] r_str;

    String prod;

    public Production(String l_str, String[] r_str, String prod) {

    this.l_str = l_str;

    this.r_str = r_str;

    this.prod = prod;

    }

    }

    private static void initProductions() {

    productions[0] = new Production("S",

    new String[]{"A", "L", String.valueOf(map_s2i.get(";"))},

    "S --> A L;");

    productions[1] = new Production("S",

    new String[]{String.valueOf(map_s2i.get("id")), "B"},

    "S --> id B");

    productions[2] = new Production("S",

    new String[]{String.valueOf(map_s2i.get("if")), String.valueOf(map_s2i.get("(")), "X", String.valueOf(map_s2i.get(")")), String.valueOf(map_s2i.get("{")), "S", String.valueOf(map_s2i.get("}")), "Q"},

    "S --> if(X){S}Q");

    productions[3] = new Production("S",

    new String[]{String.valueOf(map_s2i.get("while")), String.valueOf(map_s2i.get("(")), "X", String.valueOf(map_s2i.get(")")), String.valueOf(map_s2i.get("{")), "S", String.valueOf(map_s2i.get("}"))},

    "S --> while(X){S}");

    productions[4] = new Production("S",

    new String[]{"ε"},

    "S --> ε");

    productions[5] = new Production("B",

    new String[]{String.valueOf(map_s2i.get("(")), "L", String.valueOf(map_s2i.get(")")), String.valueOf(map_s2i.get(";"))},

    "B --> (L);");

    productions[6] = new Production("B",

    new String[]{String.valueOf(map_s2i.get("=")), "E", String.valueOf(map_s2i.get(";"))},

    "B --> =E;");

    productions[7] = new Production("L",

    new String[]{String.valueOf(map_s2i.get("id")), "L'"},

    "L --> id L'");

    productions[8] = new Production("L'",

    new String[]{String.valueOf(map_s2i.get(",")), String.valueOf(map_s2i.get("id")), "L'"},

    "L' --> ,id L'");

    productions[9] = new Production("L'",

    new String[]{"ε"},

    "L' --> ε");

    productions[10] = new Production("Q",

    new String[]{String.valueOf(map_s2i.get("else")), String.valueOf(map_s2i.get("{")), "S", String.valueOf(map_s2i.get("}"))},

    "Q --> else{S}");

    productions[11] = new Production("Q",

    new String[]{"ε"},

    "Q --> ε");

    productions[12] = new Production("X",

    new String[]{"E", "R", "E"},

    "X --> ERE");

    productions[13] = new Production("E",

    new String[]{String.valueOf(map_s2i.get("+")), "T", "E'"},

    "E --> +TE'");

    productions[14] = new Production("E",

    new String[]{String.valueOf(map_s2i.get("-")), "T", "E'"},

    "E --> -TE'");

    productions[15] = new Production("E",

    new String[]{"T", "E'"},

    "E --> TE'");

    productions[16] = new Production("E'",

    new String[]{"M", "E'"},

    "E' --> ME'");

    productions[17] = new Production("E'",

    new String[]{"ε"},

    "E' --> ε");

    productions[18] = new Production("M",

    new String[]{String.valueOf(map_s2i.get("+")), "T"},

    "M --> +T");

    productions[19] = new Production("M",

    new String[]{String.valueOf(map_s2i.get("-")), "T"},

    "M --> -T");

    productions[20] = new Production("T",

    new String[]{"F", "T'"},

    "T --> FT'");

    productions[21] = new Production("T'",

    new String[]{"N", "T'"},

    "T' --> NT'");

    productions[22] = new Production("T'",

    new String[]{"ε"},

    "T' --> ε");

    productions[23] = new Production("N",

    new String[]{String.valueOf(map_s2i.get("*")), "F"},

    "N --> *F");

    productions[24] = new Production("N",

    new String[]{String.valueOf(map_s2i.get("/")), "F"},

    "N --> /F");

    productions[25] = new Production("F",

    new String[]{String.valueOf(map_s2i.get("id"))},

    "F --> id");

    productions[26] = new Production("F",

    new String[]{String.valueOf(map_s2i.get("num"))},

    "F --> num");

    productions[27] = new Production("F",

    new String[]{String.valueOf(map_s2i.get("(")), "E", String.valueOf(map_s2i.get(")"))},

    "F --> (E)");

    productions[28] = new Production("R",

    new String[]{String.valueOf(map_s2i.get(">"))},

    "R --> >");

    productions[29] = new Production("R",

    new String[]{String.valueOf(map_s2i.get(">="))},

    "R --> >=");

    productions[30] = new Production("R",

    new String[]{String.valueOf(map_s2i.get("

    "R -->

    productions[31] = new Production("R",

    new String[]{String.valueOf(map_s2i.get("<="))},

    "R --> <=");

    productions[32] = new Production("R",

    new String[]{String.valueOf(map_s2i.get("=="))},

    "R --> ==");

    productions[33] = new Production("R",

    new String[]{String.valueOf(map_s2i.get("!="))},

    "R --> !=");

    productions[34] = new Production("S'",

    new String[]{"S", "S'"},

    "S' --> SS'");

    productions[35] = new Production("S'",

    new String[]{"ε"},

    "S' --> ε");

    productions[36] = new Production("A",

    new String[]{String.valueOf(map_s2i.get("char"))},

    "A --> char");

    productions[37] = new Production("A",

    new String[]{String.valueOf(map_s2i.get("short"))},

    "A --> short");

    productions[38] = new Production("A",

    new String[]{String.valueOf(map_s2i.get("int"))},

    "A --> int");

    productions[39] = new Production("A",

    new String[]{String.valueOf(map_s2i.get("long"))},

    "A --> long");

    productions[40] = new Production("A'",

    new String[]{String.valueOf(map_s2i.get("float"))},

    "A --> float");

    productions[41] = new Production("A",

    new String[]{String.valueOf(map_s2i.get("double"))},

    "A --> double");

    }

    main()函数的部分:

    int stackTop = 1;

    int readerTop = 0;

    int index = 0; // 当前步骤数

    initMap(); // 初始化种别码Map

    initProductions(); // 产生式初始化

    stack.add(0, String.valueOf(map_s2i.get("$"))); // 在stack底部加上$

    stack.add(stackTop, "S'"); // 将S'压入栈

    2.读入词法分析结果

    System.out.print("请输入词法分析结果的文件路径:");

    Scanner scanner = new Scanner(System.in);

    String filepath = scanner.next();

    StringBuffer outputBuffer = new StringBuffer(); // 输出到文件的StringBuffer

    // 通过词法分析器的输出结果,初始化reader

    try {

    readToReader(filepath);

    } catch (IOException e) {

    e.printStackTrace();

    }

    reader.add(map_s2i.get("$")); // 在reader末尾加上$

    public static void readToReader(String filePath) throws IOException {

    InputStream is = new FileInputStream(filePath);

    String line; // 用来保存每行读取的内容

    BufferedReader br = new BufferedReader(new InputStreamReader(is));

    line = br.readLine(); // 读取第一行

    while (line != null) { // 如果 line 为空说明读完了

    int pos = line.indexOf(",");

    reader.add(Integer.valueOf(line.substring(0, pos)));

    line = br.readLine(); // 读取下一行

    }

    br.close();

    is.close();

    }

    注意到我们在stack和reader末尾都添加了$,当两者的$匹配时表示语法分析结束。

    3.语法分析

    语法分析的输出需要描述分析的过程,每一步分析需要列出当前栈、待读队列、下一步所用产生式。

    示例输出如下:

    682c1617d66d2793db4afa3076043b4c.png

    语法分析的步骤是:

    1.输出当前栈的内容:从栈内依次取出栈顶符号,判断该符号是种别码还是字符,若为种别码,需将其对应转换成单词,若转换时抛出NumberFormatException,则说明是字符。将结果放入输出的buffer中。

    注意,此处引入StringBuffer sb仅为控制在控制台的输出格式对齐。

    2.输出待读队列:遍历输出reader的内容。

    3.将reader队列第一个和stack当前栈栈顶元素进行匹配。若相同,说明是同一个终结符;若不同,则根据LL(1)预测分析表预测下一步推导所用产生式。

    main()函数部分:

    while (stackTop >= 0) {

    System.out.printf("%-6s", "第" + ++index + "步:");

    System.out.printf("%-10s", "当前栈:");

    outputBuffer.append("第" + index + "步: 当前栈:");

    StringBuffer sb = new StringBuffer(); // 引入StringBuffer仅为控制在控制台的输出格式对齐

    for (int i = 0; i <= stackTop; i++) {

    String str = null;

    try {

    str = map_i2s.get(Integer.valueOf(stack.get(i)));

    if (str != null) {

    sb.append(str + " ");

    outputBuffer.append(str + " ");

    }

    } catch (NumberFormatException e) {

    sb.append(stack.get(i) + " ");

    outputBuffer.append(stack.get(i) + " ");

    }

    }

    System.out.printf("%-30s", sb.toString());

    System.out.print("待读队列:");

    outputBuffer.append(" 待读队列:");

    sb = new StringBuffer();

    for (int i = 0; i < reader.size(); i++) {

    sb.append(map_i2s.get(reader.get(i)) + " ");

    outputBuffer.append(map_i2s.get(reader.get(i)) + " ");

    }

    System.out.printf("%-55s", sb.toString());

    if (match(stackTop, readerTop)) {

    stackTop--;

    System.out.print("\n");

    outputBuffer.append("\n");

    } else {

    int i = ll1_table(stackTop, readerTop);

    stackTop += stackPush(stackTop, productions[i]); // 压栈

    System.out.printf("%-30s", "下一步所用产生式:" + productions[i].prod);

    System.out.println();

    outputBuffer.append(" 下一步所用产生式:" + productions[i].prod + "\n");

    }

    }

    if (stackTop == -1) {

    System.out.println("语法分析成功");

    outputBuffer.append("Accept");

    }

    检测reader头部和stack顶部是否匹配,返回匹配结果

    private static boolean match(int stackTop, int readerTop) {

    try {

    int stackTopVal = Integer.valueOf(stack.get(stackTop)); // 未抛出异常说明是终结符

    if (stackTopVal == reader.get(0)) {

    stack.remove(stackTop);

    reader.remove(readerTop);

    return true;

    } else {

    return false;

    }

    } catch (NumberFormatException e) {

    // 抛出异常说明是非终结符

    return false;

    }

    }

    利用LL(1)预测分析表进行分析,返回单词种别码。

    private static int ll1_table(int stackTop, int readerTop) {

    if ("S".equals(stack.get(stackTop))) {

    if ("char".equals(map_i2s.get(reader.get(readerTop)))) {

    return 0;

    } else if ("short".equals(map_i2s.get(reader.get(readerTop)))) {

    return 0;

    } else if ("int".equals(map_i2s.get(reader.get(readerTop)))) {

    return 0;

    } else if ("long".equals(map_i2s.get(reader.get(readerTop)))) {

    return 0;

    } else if ("float".equals(map_i2s.get(reader.get(readerTop)))) {

    return 0;

    } else if ("double".equals(map_i2s.get(reader.get(readerTop)))) {

    return 0;

    } else if ("id".equals(map_i2s.get(reader.get(readerTop)))) {

    return 1;

    } else if ("if".equals(map_i2s.get(reader.get(readerTop)))) {

    return 2;

    } else if ("while".equals(map_i2s.get(reader.get(readerTop)))) {

    return 3;

    } else if ("}".equals(map_i2s.get(reader.get(readerTop)))) {

    return 4;

    } else if ("$".equals(map_i2s.get(reader.get(readerTop)))) {

    return 4;

    } else {

    return -1;

    }

    } else if ("B".equals(stack.get(stackTop))) {

    if ("(".equals(map_i2s.get(reader.get(readerTop)))) {

    return 5;

    } else if ("=".equals(map_i2s.get(reader.get(readerTop)))) {

    return 6;

    } else {

    return -1;

    }

    } else if ("L".equals(stack.get(stackTop))) {

    if ("id".equals(map_i2s.get(reader.get(readerTop)))) {

    return 7;

    } else {

    return -1;

    }

    } else if ("L'".equals(stack.get(stackTop))) {

    if (";".equals(map_i2s.get(reader.get(readerTop)))) {

    return 9;

    } else if (")".equals(map_i2s.get(reader.get(readerTop)))) {

    return 9;

    } else if ("}".equals(map_i2s.get(reader.get(readerTop)))) {

    return 9;

    } else if ("$".equals(map_i2s.get(reader.get(readerTop)))) {

    return 9;

    } else if (",".equals(map_i2s.get(reader.get(readerTop)))) {

    return 8;

    } else {

    return -1;

    }

    } else if ("Q".equals(stack.get(stackTop))) {

    if ("}".equals(map_i2s.get(reader.get(readerTop)))) {

    return 11;

    } else if ("$".equals(map_i2s.get(reader.get(readerTop)))) {

    return 11;

    } else if ("else".equals(map_i2s.get(reader.get(readerTop)))) {

    return 10;

    } else {

    return -1;

    }

    } else if ("X".equals(stack.get(stackTop))) {

    if ("id".equals(map_i2s.get(reader.get(readerTop)))) {

    return 12;

    } else if ("num".equals(map_i2s.get(reader.get(readerTop)))) {

    return 12;

    } else if ("+".equals(map_i2s.get(reader.get(readerTop)))) {

    return 12;

    } else if ("-".equals(map_i2s.get(reader.get(readerTop)))) {

    return 12;

    } else if ("(".equals(map_i2s.get(reader.get(readerTop)))) {

    return 12;

    } else {

    return -1;

    }

    } else if ("E".equals(stack.get(stackTop))) {

    if ("id".equals(map_i2s.get(reader.get(readerTop)))) {

    return 15;

    } else if ("num".equals(map_i2s.get(reader.get(readerTop)))) {

    return 15;

    } else if ("(".equals(map_i2s.get(reader.get(readerTop)))) {

    return 15;

    } else if ("+".equals(map_i2s.get(reader.get(readerTop)))) {

    return 13;

    } else if ("-".equals(map_i2s.get(reader.get(readerTop)))) {

    return 14;

    } else {

    return -1;

    }

    } else if ("E'".equals(stack.get(stackTop))) {

    if ("+".equals(map_i2s.get(reader.get(readerTop)))) {

    return 16;

    } else if ("-".equals(map_i2s.get(reader.get(readerTop)))) {

    return 16;

    } else if (">".equals(map_i2s.get(reader.get(readerTop)))) {

    return 17;

    } else if (">=".equals(map_i2s.get(reader.get(readerTop)))) {

    return 17;

    } else if ("

    return 17;

    } else if ("<=".equals(map_i2s.get(reader.get(readerTop)))) {

    return 17;

    } else if ("==".equals(map_i2s.get(reader.get(readerTop)))) {

    return 17;

    } else if ("!=".equals(map_i2s.get(reader.get(readerTop)))) {

    return 17;

    } else if (";".equals(map_i2s.get(reader.get(readerTop)))) {

    return 17;

    } else if (")".equals(map_i2s.get(reader.get(readerTop)))) {

    return 17;

    } else {

    return -1;

    }

    } else if ("M".equals(stack.get(stackTop))) {

    if ("+".equals(map_i2s.get(reader.get(readerTop)))) {

    return 18;

    } else if ("-".equals(map_i2s.get(reader.get(readerTop)))) {

    return 19;

    } else {

    return -1;

    }

    } else if ("T".equals(stack.get(stackTop))) {

    if ("id".equals(map_i2s.get(reader.get(readerTop)))) {

    return 20;

    } else if ("num".equals(map_i2s.get(reader.get(readerTop)))) {

    return 20;

    } else if ("(".equals(map_i2s.get(reader.get(readerTop)))) {

    return 20;

    }

    } else if ("T'".equals(stack.get(stackTop))) {

    if ("+".equals(map_i2s.get(reader.get(readerTop)))) {

    return 22;

    } else if ("-".equals(map_i2s.get(reader.get(readerTop)))) {

    return 22;

    } else if ("*".equals(map_i2s.get(reader.get(readerTop)))) {

    return 21;

    } else if ("/".equals(map_i2s.get(reader.get(readerTop)))) {

    return 21;

    } else if (">".equals(map_i2s.get(reader.get(readerTop)))) {

    return 22;

    } else if (">=".equals(map_i2s.get(reader.get(readerTop)))) {

    return 22;

    } else if ("

    return 22;

    } else if ("<=".equals(map_i2s.get(reader.get(readerTop)))) {

    return 22;

    } else if ("==".equals(map_i2s.get(reader.get(readerTop)))) {

    return 22;

    } else if ("!=".equals(map_i2s.get(reader.get(readerTop)))) {

    return 22;

    } else if (";".equals(map_i2s.get(reader.get(readerTop)))) {

    return 22;

    } else if (")".equals(map_i2s.get(reader.get(readerTop)))) {

    return 22;

    } else {

    return -1;

    }

    } else if ("N".equals(stack.get(stackTop))) {

    if ("*".equals(map_i2s.get(reader.get(readerTop)))) {

    return 23;

    } else if ("/".equals(map_i2s.get(reader.get(readerTop)))) {

    return 24;

    } else {

    return -1;

    }

    } else if ("F".equals(stack.get(stackTop))) {

    if ("id".equals(map_i2s.get(reader.get(readerTop)))) {

    return 25;

    } else if ("num".equals(map_i2s.get(reader.get(readerTop)))) {

    return 26;

    } else if ("(".equals(map_i2s.get(reader.get(readerTop)))) {

    return 27;

    } else {

    return -1;

    }

    } else if ("R".equals(stack.get(stackTop))) {

    if (">".equals(map_i2s.get(reader.get(readerTop)))) {

    return 28;

    } else if (">=".equals(map_i2s.get(reader.get(readerTop)))) {

    return 29;

    } else if ("

    return 30;

    } else if ("<=".equals(map_i2s.get(reader.get(readerTop)))) {

    return 31;

    } else if ("==".equals(map_i2s.get(reader.get(readerTop)))) {

    return 32;

    } else if ("!=".equals(map_i2s.get(reader.get(readerTop)))) {

    return 33;

    } else {

    return -1;

    }

    } else if ("S'".equals(stack.get(stackTop))) {

    if ("char".equals(map_i2s.get(reader.get(readerTop)))) {

    return 34;

    } else if ("short".equals(map_i2s.get(reader.get(readerTop)))) {

    return 34;

    } else if ("int".equals(map_i2s.get(reader.get(readerTop)))) {

    return 34;

    } else if ("long".equals(map_i2s.get(reader.get(readerTop)))) {

    return 34;

    } else if ("float".equals(map_i2s.get(reader.get(readerTop)))) {

    return 34;

    } else if ("double".equals(map_i2s.get(reader.get(readerTop)))) {

    return 34;

    } else if ("id".equals(map_i2s.get(reader.get(readerTop)))) {

    return 34;

    } else if ("if".equals(map_i2s.get(reader.get(readerTop)))) {

    return 34;

    } else if ("while".equals(map_i2s.get(reader.get(readerTop)))) {

    return 34;

    } else if ("$".equals(map_i2s.get(reader.get(readerTop)))) {

    return 35;

    } else {

    return -1;

    }

    } else if ("A".equals(stack.get(stackTop))) {

    if ("char".equals(map_i2s.get(reader.get(readerTop)))) {

    return 36;

    } else if ("short".equals(map_i2s.get(reader.get(readerTop)))) {

    return 37;

    } else if ("int".equals(map_i2s.get(reader.get(readerTop)))) {

    return 38;

    } else if ("long".equals(map_i2s.get(reader.get(readerTop)))) {

    return 39;

    } else if ("float".equals(map_i2s.get(reader.get(readerTop)))) {

    return 40;

    } else if ("double".equals(map_i2s.get(reader.get(readerTop)))) {

    return 41;

    } else {

    return -1;

    }

    } else {

    System.out.println("语法错误");

    }

    return -1;

    }

    4.输出结果到文件

    System.out.print("请输入语法分析结果文件的保存路径:");

    String outputPath = scanner.next();

    // 将StringBuffer的内容输出到文件

    File outputFile = new File(outputPath);

    if (outputFile.exists()) {

    outputFile.delete();

    }

    PrintWriter writer = null;

    try {

    outputFile.createNewFile();

    writer = new PrintWriter(new FileOutputStream(outputFile));

    writer.write(outputBuffer.toString());

    } catch (IOException e1) {

    e1.printStackTrace();

    } finally {

    if (writer != null) {

    writer.close();

    }

    }

    八、运行结果

    输入词法分析器的代码块:

    f74210abcc6d334d6a289a580b6a53ea.png

    词法分析器结果:

    e36d9fd7a5fc6029c69e30b7afa9867f.png

    5cb716ad70fca65c48d245d3251c8b88.png

    语法分析结果:

    ad01209504e51c48b7ed424aec0b9544.png

    ……

    e061b5ccf409ed6a78429cbc63ede185.png

    至此,语法分析器编写完成。如有问题,欢迎交流指正。

    2019-10-16补充stackPush方法:

    private static int stackPush(int stackTop, Production production) {

    int len = production.r_str.length;

    stack.remove(stackTop);

    if ("ε".equals(production.r_str[0])) {

    } else {

    for (int i = len - 1; i >= 0; i--) {

    stack.add(production.r_str[i]);

    }

    return len - 1;

    }

    return -1;

    }

    展开全文
  • 实验2 递归下降语法分析程序设计

    千次阅读 2020-06-21 21:15:18
    (1)理解语法分析在编译程序中的作用,以及它与词法分析程序的关系 (2)加深对递归下降语法分析原理的理解 (3)掌握递归下降语法分析的实现方法 【实验内容】 编制一个递归下降分析程序,实现对词法分析程序提供...
  • 编译原理——实验2 递归下降语法分析程序设计 【实验要求】 (1)待分析的简单语言的词法同实验1 (2)待分析的简单语言的语法 用扩充的BNF表示如下: 1)<程序>::=begin<语句串>end 2) <...
  • ③完成语法分析程序设计和实现。 ④程序能完成对指定语言的语法分析。 重点及难点:熟悉算符优先分析等语法分析方法,掌握语法分析的一般过程。在此基础上完成基于算数表达式的语法分析程序设计和调试运行。 一....
  • 递归下降语法分析程序设计

    千次阅读 2016-09-13 22:53:19
    实验目的】  练习构造递归下降语法分析程序的方法,熟悉上下文无关文法的使用,... 利用某一高级程序设计语言构造语法分析程序  【具体要求】对于给定的文法G[E]  E->TE’  E’->+TE’ | ε  T->FT’
  • 接下来我们讨论自底向上的语法分析。自底向上的语法分析过程同样对应于为一个输入串构造语法分析树的过程,只不过是从叶子节点(底部)逐渐向上到达根节点(顶部)。自底向上分析法的解析力量比自顶向下分析法要强大...
  • 通过设计、编制、调试一个典型的赋值语句的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查,进一步掌握常用的语法分析方法。
  • 任选一种有代表性的语法分析方法,如算符优先法、递归下降法、LL(1)、SLR(1)、LR(1)等,通过设计、编制、调试实现一个典型的语法分析程序,对实验一所得扫描器提供的单词序列进行语法检查和结构分析,实现并进一步...
  • 递归下降语法分析程序的范例代码...实验内容及操作示范详见实验指导书...
  • 编写一个语法分析程序,对于给定的输入串,能够判断识别该串是否为给定文法的句型。 【实验步骤和要求】 1.从键盘读入输入串,并判断正误; 2.若无误,由程序自动构造FIRST、FOLLOW集以及SELECT集合,判断是否为...
  • #include<stdio.h> #include<string> char str[10]; //记录要分析的字符串 int x=0; //记录第一个字符 void E(); void X(); void T(); void Y(); void F(...
  • #include<stdio.h> #include<string> charstr[10]; //记录要分析的字符串 intx=0; //记录第一个字符 voidE(); voidX(); voidT(); voi...
  • #include<stdio.h> #include<string> char str[10]; //记录要分析的字符串 int x=0; //记录第一个字符 void E(); void X(); void T(); void Y(); void F()...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,081
精华内容 1,232
关键字:

语法分析程序设计