设计要求:对于任意输入的一个LL(1)文法,构造其预测分析表,并对指定输入串分析其是否为该文法的句子。

思路:首先实现集合FIRST(X)构造算法和集合FOLLOW(A)构造算法,再根据FIRST和FOLLOW集合构造出预测分析表,并对指定的句子打印出分析栈的分析过程,判断是否为该文法的句子。

指定文法:

//文法
E->TK
K->+TK
K->$
T->FM
M->*FM
M->$
F->i
F->(E)

对于输入串i+i*i# ,这里我们先给出实验结果截图:

这个实验花了我一天的时间,主要难点在于first集和follow集中的递归判断部分,其他的只要按照下面的判断流程走就可以了。

(1)求FIRST集的算法思想

如果产生式右部第一个字符为终结符,则将其计入左部first集
 如果产生式右部第一个字符为非终结符
 ->求该非终结符的first集
 ->将该非终结符的非$first集计入左部的first集
->若存在$,则将指向产生式的指针右移
->若不存在$,则停止遍历该产生式,进入下一个产生式
->若已经到达产生式的最右部的非终结符,则将$加入左部的first集
 处理数组中重复的first集中的终结符

(2)求FOLLOW集的算法思想

对于文法G中每个非终结符A构造FOLLOW(A)的办法是,连续使用下面的规则,直到每个FOLLOW不在增大为止.
(1) 对于文法的开始符号S,置#于FOLLOW(S)中;
(2) 若A->aBb是一个产生式,则把FIRST(b)\{ε}加至FOLLOW(B)中;
(3) 若A->aB是一个产生式,或A->aBb是一个产生式而b=>ε(即ε∈FIRST(b))则把FOLLOW(A)加至FOLLOW(B)中

(3)生成预测分析表的算法思想

构造分析表M的算法是: 
 (1) 对文法G的每个产生式A->a执行第二步和第三步;
 (2) 对每个终结符a∈FIRST(a),把A->a加至M[A,a]中;
 (3) 若ε∈FIRST(a),则把任何b∈FOLLOW(A)把A->a加至M[A,b]中;
 (4) 把所有无定义的M[A,a]标上出错标志.

(4)对符号串的分析过程

预测分析程序的总控程序在任何时候都是按STACK栈顶符号X和当前的输入符号行事的,对于任何(X,a),总控程序
 每次都执行下述三种可能的动作之一;
(1) 若X=a=”#”,则宣布分析成功,停止分析过程.
(2) 若X=a≠”#”,则把X从STACK栈顶逐出,让a指向下一个输入符号.
(3) 若X是一个非终结符,则查看分析表M,若M[A,a]中存放着关于X的一个产生式,那么,首先把X逐出STACK栈顶,然后
把产生式的右部符号串按反序一一推进STACK栈(若右部符号为ε,则意味着不推什么东西进栈).在把产生式的右部
符号推进栈的同时应做这个产生式相应得语义动作,若M[A,a]中存放着”出错标志”,则调用出错诊察程序ERROR.

在我的程序中,Base类为基类,负责求出FIRST和FOLLOW集;TableStack继承Base类,求出预测分析表和显示符号串的分析过程。

Base.h

struct node
{char left;string right;
};class Base
{
protected:int T;node analy_str[100]; //输入文法解析set<char> first_set[100];//first集set<char> follow_set[100];//follow集vector<char> ter_copy; //去$终结符vector<char> ter_colt;//终结符vector<char> non_colt;//非终结符public:Base() :T(0){}bool isNotSymbol(char c);int get_index(char target);//获得在终结符集合中的下标int get_nindex(char target);//获得在非终结符集合中的下标void get_first(char target); //得到first集合void get_follow(char target);//得到follow集合void inputAndSolve(); //处理得到first和followvoid display(); //显示};

TableStack.h

class TableStack :public Base
{
protected:vector<char> to_any; //分析栈vector<char> left_any;//剩余输入串int tableMap[100][100];//预测表
public:TableStack(){ memset(tableMap, -1, sizeof(tableMap)); }void get_table(); //得到预测表void analyExp(string s); //分析栈的处理void print_out();//输出void getAns(); //结合处理
};

接下来只列出FIRST集中的核心递归过程,有详细注释:

void Base::get_first(char target)
{int tag = 0;int flag = 0;for (int i = 0; i<T; i++){if (analy_str[i].left == target)//匹配产生式左部{if (!isNotSymbol(analy_str[i].right[0]))//对于终结符,直接加入first{first_set[get_index(target)].insert(analy_str[i].right[0]);}else{for (int j = 0; j<analy_str[i].right.length(); j++){if (!isNotSymbol(analy_str[i].right[j]))//终结符结束{first_set[get_index(target)].insert(analy_str[i].right[j]);break;}get_first(analy_str[i].right[j]);//递归//   cout<<"curr :"<<analy_str[i].right[j];set<char>::iterator it; for (it = first_set[get_index(analy_str[i].right[j])].begin(); it != first_set[get_index(analy_str[i].right[j])].end(); it++){if (*it == '$')flag = 1;elsefirst_set[get_index(target)].insert(*it);//将FIRST(Y)中的非$就加入FIRST(X)}if (flag == 0)break;else{tag += flag;flag = 0;}}if (tag == analy_str[i].right.length())//所有右部first(Y)都有$,将$加入FIRST(X)中first_set[get_index(target)].insert('$');}}}}

这个语法分析的全部工程代码在我的 Github 上,欢迎大家star学习,希望可以给大家带来帮助。

编译原理:LL(1)文法 语法分析器(预测分析表法)相关推荐

  1. 编译原理:LL(1)语法分析器的实现(内含代码详细注释)

     自顶向下语法分析器的设计与实现 目录 一.说明 二.程序功能及运行截图 功能 运行截图 三.算法逻辑和程序流程图 定义的主要变量或存储结构 (1)消除直接左递归 (2)求FIRST集合 (3)求FO ...

  2. 编译原理课程设计:语法分析器

    配套代码: 编译原理课程设计:语法分析器-Python文档类资源-CSDN下载所使用的开发环境:Windows10.python(PyCharm)环境注意:expression更多下载资源.学习资料请 ...

  3. 从0开始的python学习:编译原理实验4:语法分析器1--预测分析器构造

    这里刚开始试用python的函数功能,可能把局部变量和全局变量给写乱了,后期交之前还想再优化的时候发现越改越乱,太真实的hhh 实验四:语法分析器1–预测分析器构造 实验目的: 通过编写一个预测分析器 ...

  4. 编译原理实验-递归下降语法分析器的构建

    实验目的: 针对给定的上下文无关文法,编制一个递归下降分析程序. 分析: 递归下降语法分析的前提是保证LL(1)文法 递归下降的思路就是暴力dfs.对每个程序直接不管三七二十一搜进去,只要能搜到就继续 ...

  5. 语法分析器---预测分析程序

    实验二  预测分析算法的设计与实现 (8学时) 一.实验目的 通过预测分析算法的设计与实现,加深对自上而下语法分析方法的理解,尤其是对自上而下分析条件的理解. 二.实验要求   输入文法及待分析的输入 ...

  6. c语言语法分析源程序,深入浅出编译原理-5-一个简单语法分析器的C语言实现

    引言 前面已经介绍了编译器的预处理,词法分析,词法分析器的实现,也在其中说到了语法分析的任务和过程. 语法分析的输入是词法单元序列,然后根据语言的文法表示(展开式),利用有限状态机理论,生成抽象语法树 ...

  7. 实验4 基于预测分析表法的语法分析程序_第三十届 脑功能磁共振数据处理分析培训班...

    北京赛博尔医药科技有限公司(www.cibrmed.com)将于2019年 7月6日 至 2019年7月11日(周六至下周四)举办第三十届脑功能磁共振数据处理分析培训班(课程内容详见课表安排).欢迎大 ...

  8. 编译原理——自上而下的语法分析方法(LL分析法)

    自上而下的语法分析方法(LL分析法) 概述: 语法分析的地位:编译程序的核心部分 任务:词法分析出来的单词序列是否是给定文法的句子 理论:上下文无关文法和下推自动机 方式:自上而下的语法分析(推导)和 ...

  9. 4.2.5 预测分析法与预测分析表的构造

    4.2.5 预测分析法与预测分析表的构造 预测分析法也称为 LL ( 1 )分析法.这种分析法是确定的自上而下分析的另一种方法,采用这种方法进行语法分析要求描述语言的文法是 LL ( 1 )文法. 一 ...

最新文章

  1. 漫谈可视化Prefuse(四)---被玩坏的Prefuse API
  2. python 正则search 所有_python之路----正则re(search,match,findall……)
  3. root cause of error messagw for a mixed usage of 01 and 03
  4. [C++STL]queue容器用法介绍
  5. linux 串口 qt,Linux-QT4.7 实现串口通信
  6. echarts的dataZoom属性在移动端 h5+环境中无法左右滑动问题
  7. [Linux网络编程]ARP简单实例
  8. LeetCode(637)——二叉树的层平均值(JavaScript)
  9. vuex 在typescript中的写法
  10. jmeter安装插件的方法
  11. (Kinetis K60) FTM输出PWM
  12. java 时钟_Java的指针时钟
  13. make makefile cmake qmake都是什么,有什么区别
  14. 程序员有哪些必备技能?
  15. 华为鸿蒙生态班怎么上,华为联合西北工业大学开设“鸿蒙生态菁英班”: 50 人左右...
  16. 自学C语言入门教程(上)
  17. java中调用谷歌的无界浏览器对页面元素进行截图
  18. 古代平朔历法基本算法
  19. TP-LINK 企业路由器 PPTP 配置
  20. 维克森林大学计算机科学专业好不好,维克森林大学商业分析硕士怎么样?

热门文章

  1. spss三次指数平滑_15.2.2 指数平滑模型的SPSS操作(1)
  2. LTE(4G) - NR(5G) RSRP和SINR RSRQ RSSI LTE信号质量
  3. 视频中的音频提取如何操作?一分钟教会你
  4. python菱形图案_「每日一练」巧用python输出菱形图案
  5. 服务器金属外壳刮花了怎么修复,pc拉杆箱被磨了怎么办?3方法快速修复(附防刮方式)...
  6. Macbook Pro上手手札
  7. 大数据技术的概论(2)
  8. 电源设计经验谈1-9
  9. 点到点轨迹规划——三次曲线,五次曲线,梯形曲线,S曲线
  10. OpenCV之findContours获取轮廓(Python版)