编译原理-简单的递归下降语法分析器LL(1)

在网上看了很多篇关于递归下降分析器的博文,均没有满意的,一是所写的程序不对、二是解释的不够清楚。所以想自己写一篇,顺便总结一下所学。

递归下降分析法

递归下降分析法的原理是利用函数之间的递归调用来模拟语法树自上而下的构建过程。从根节点出发,自顶向下为输入串中寻找一个最左匹配序列,建立一棵语法树。在不含左递归和每个非终结符的所有候选终结首字符集都两两不相交条件下,我们就可能构造出一个不带回溯的自顶向下的分析程序,这个分析程序是由一组递归过程(或函数)组成的,每个过程(或函数)对应文法的而一个非终结符。

准备知识

对文法中的每一个非终结符计算它们的Fisrt集,Follow集和Select集。感觉书上的定义是真的难理解,下面不贴定义和数学符号,仅贴博主个人的理解。

  • 计算First集
    1. 终结符的First集是它本身;
    2. 若非终结符A可以推出以终结符开头的串,那么这个终结符属于
    Fisrt(A);若A可以推导出空串ε,那么空串ε属于First(A);
    3. A->B… 是一个产生式,B是一个非终结符,那么First(B)中除去空串ε都包含在First(A);
    4. 若A是非终结符;B1,B2,…,Bi 也是非终结符,且有产生式 A->B1 B2 … Bn;当B1,B2 … Bn-1都能推导出ε时,则First(B1)、FIRST(B2)、…、First(Bn-1)的所有非空元素和First(Bn) 包含在First(A)中;
    5. 若4中B1,B2 … Bn都能推导出ε时则First(B1)、FIRST(B2)、…、First(Bn)的所有非空元素包含在First(A)中,并且ε属于First(A)。
  • 计算Follow集
    Follow集合,顾名思义,就是文法符号后面可能跟随的终结符的集合(不包括空串ε)。Follow集针对的是非终结符。
    1. 首先设 S 为文法中开始符号,把 {#} 加入Follow(S)中;
    2. 若A->αBβ 是一个产生式,则把First(β)的非空元素加入
    Follow(B)中。如果β能够推导出ε则把Follow(A)也加入Follow(B)中,以此类推。
  • 计算Select集
    给定上下文无关文法的产生式A->α,A是非终结符, 若α不能推导出ε,则Select(A->α)=First(α); 如果α能推导出ε,Select(A->α)=(First(α) –{ε})∪Follow(A)。

示例

文法G:
E->TE’
E’->+E|ε
T->FT’
T’->T|ε
F->PF’
F’->*F’|ε
P->(E)|a|b|v
经过计算的Select集为:
Select(E->TE’) = {(,a,b,v}
Select(E’->+E) = {(,+}
Select(E’->ε) = {(,#}
Select(T->FT’) = {(,a,b,v}
Select(T’->T) = {(,a,b,v}
Select(T’->ε) = {+,),#}
Select(F->PF’) = {(,a,b,v}
Select(F’->*F’) = {*}
Select(F’->ε) = {(,a,b,v,),+,#}
Select(P->(E)) = {(}
Select(P->a) = {a}
Select(P->b) = {b}
Select(P->v) = {v}

程序实现

  1. 每一个非终结符对应于一个函数(子过程);
  2. 非终结符所对应的右侧产生式为函数体;
  3. 每遇到一个终结符,则需要判断所输入字符是否与之匹配,若匹配则读取下一个,若不匹配,则进行出错处理。
C语言代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>#define LEN 100char str[LEN];
int i;
bool flag=true;void E();
void E1();
void T();
void T1();
void F();
void F1();
void P();int main(){int m;printf("请输入测试的次数:");scanf("%d",&m);while(m--){printf("请输入字符串(以#结束):");scanf("%s",&str);i=0;E();if(flag==true){printf("%s为合法字符串!\n",str);}else{printf("%s为非法字符串!\n",str);}strcpy(str,"");}
} void E(){if(flag){if(str[i]=='('||str[i]=='a'||str[i]=='b'||str[i]=='v'){T();E1();}else{flag=false;}}
}void E1(){if(flag){if(str[i]=='+'){i++;E();}else if(str[i]!='#'&&str[i]!=')'){flag=false;}}
}void T(){if(flag){if(str[i]=='('||str[i]=='a'||str[i]=='b'||str[i]=='v'){F();T1();}else{flag=false;}}
}void T1(){if(flag){if(str[i]=='('||str[i]=='a'||str[i]=='b'||str[i]=='v'){T();}else if(str[i]!='+'&&str[i]!=')'&& str[i]!='#'){flag = false;}}
}void F(){if(flag){ if(str[i]=='('||str[i]=='a'||str[i]=='b'||str[i]=='v'){P();F1();}else{flag=false;}}
}void F1(){if(flag){if(str[i]=='*'){i++;F1();}else if(str[i]!='('&&str[i]!='a'&&str[i]!='b'&&str[i]!='v'&&str[i]!='+'&&str[i]!=')'&&str[i]!='#'){flag = false;}}
}void P(){if(flag){if(str[i]=='('){i++;E();if(str[i]==')'){i++;}}else if(str[i]=='a'){i++;}else if(str[i]=='b'){i++;}else if(str[i]=='v'){i++;}else{flag=false;}}
}

编译原理-递归下降分析器相关推荐

  1. 编译原理8:递归下降分析器、扩充巴斯克范式、JavaCC

    递归下降分析器 递归下降分析器设计示例 E'不考虑follow集的隐患会被后续的子程序考虑到,所以没有问题 扩充的巴科斯范式和语法图 JavaCC简介 小结

  2. C++:编译实验之递归下降分析器

    一.实验目的 1.加深对递归下降分析法一种自顶向下的语法分析方法的理解. 2.根据文法的产生式规则消除左递归,提取公共左因子构造出相应的递归下降分析器. 二.实验内容 根据课堂讲授的形式化算法,编制程 ...

  3. java实验文法报告_西安邮电大学编译原理LL文法分析器实验(java).doc

    西安邮电大学编译原理LL文法分析器实验(java) <编译原理>实验报告 题目: 语法分析器的制作 学生姓名: 班 级: 软件1202 学 号: 指导教师: 成 绩: 西安邮电大学计算机学 ...

  4. 《Python Cookbook 3rd》笔记(2.19):实现一个简单的递归下降分析器

    实现一个简单的递归下降分析器 问题 你想根据一组语法规则解析文本并执行命令,或者构造一个代表输入的抽象语法树.如果语法非常简单,你可以自己写这个解析器,而不是使用一些框架. 解法 在这个问题中,我们集 ...

  5. 编译原理简单语法分析器(first,follow,分析表)源码下载

    编译原理(简单语法分析器下载) http://files.cnblogs.com/files/hujunzheng/%E5%8A%A0%E5%85%A5%E5%90%8C%E6%AD%A5%E7%AC ...

  6. 深入浅出编译原理-3-词法分析器

    引言 编译器的工作的开始,就是读入源码(预编译先不考虑),然后,去除一些空字符,然后经过词素匹配,并和其属性(可选),组成一个的词法单元,多个词法单元,连接成词法单元序列.自此,此法分析器的工作就算完 ...

  7. [编译原理]构造LR分析器和SLR移进归约分析表

    目录 目标 1.基础知识引入 1.1 文法 1.2 拓广文法 1.3 全部的项目集 2. 计算文法的LR(0)项目集的.识别活前缀的DFA 2.1 分析得到各个项目集 2.2 构建SLR分析表中的移进 ...

  8. 递归下降分析器的设计java_数据结构(Java版)教与学(48和60学时教学大纲)

    baba<数据结构>课程教学大纲课程中文名称: 数据结构.课程英文名称:Data Structures.课程类别:专业基础课 必修.课程学分数:4(16学时为1学分)课程学时数:讲课48学 ...

  9. 编译原理-6-LR语法分析器

    LR语法分析器 自顶向下的.不断归约的.基于句柄识别自动机的.适用于LR(∗) 文法的.LR(∗) 语法分析器 只考虑无二义性的文法 1. 构建语法树过程 自底向上构建语法分析树 根节点是文法的起始符 ...

最新文章

  1. Java设计模式(十三):代理设计模式
  2. python PIL(pillow) Image模块的基础功能
  3. C#操作Access数据库
  4. qchart折现图_Qt开发技术:QCharts(二)QCharts折线图介绍、Demo以及代码详解
  5. 互联网金融盯上房地产资金饥渴症
  6. C++函数的返回值,你不懂得!陷阱无处不在!
  7. 简单区块链Python实现
  8. 【Python】基于Python的百度迁徙3——城内出行强度(附代码)
  9. html手机网页新闻模板,新浪手机新闻网站模板首页html源码
  10. 博客园怎样在Markdown编辑模式下调整图片大小(已解决)
  11. day12 函数高级
  12. CSJ加人|cs如何加人|cs加人快捷键
  13. 参考文献标引方式_参考文献的正确标注方法
  14. 爬虫之短信验证码自动化接收——Tasker
  15. HFSS仿真侧馈微带天线学习笔记
  16. JWPlayer Flash播放器如何实现视频分段载入播放从而节省带宽?
  17. IDEA中如何将一个JavaWeb项目打包成war包
  18. HTTP状态码 201 304 404 500等代表的含义
  19. 数据结构二叉排序树的查找
  20. 海奥华预言--第十一章 谁是基督?

热门文章

  1. js做网站301跳转
  2. 网络化的智能温度传感器设计
  3. 这是一篇关于HaaS 506的小Tips
  4. java程序阅读填空题_JAVA练习题
  5. 巨推荐!文献下载利器!6个网站可随时随地免费下载中文文献!
  6. uart接口介绍和认识
  7. 在阿里云ECS服务器上搭建FTP服务
  8. 请更换备份电池 pos机_POS机常见问题及处理方法
  9. Github入门指南
  10. Docker系列 WordPress系列 你需要个人博客吗