参考来源:聊聊编译原理(二) - 语法分析

自顶向下分析方法

自顶向下分析方法:递归下降分析法,LL1分析法。其实本质上核心思想是一样的,也就是LL,从左至右,最左推导,因而我觉得其实可以把前一个称为LL0分析法,即不使用向前看符号,这也是他们的不同点,具体实现不同罢了,递归下降需要用回溯和分治,调用递归函数,因为递归调用,耗费时间当然要长一点,而LL1使用first和follow函数(当然前者也用到了)创建了一个预测分析表,可以知道,这个算法不需要再去遍历尝试每一种语法树组合,而是根据表肯定能选出最优的组合去匹配,这也就是典型的牺牲空间换时间的算法。

TINY文法


为简单起见,丢弃了read和write语句(但实际上也就加两条语法的问题,可直接补充)

program -> stmt-sequence
stmt-sequence -> stmt-sequence;statement | statement
statement -> if-stmt | repeat-stmt | assign-stmt //丢弃了读写语句
if-stmt -> if exp then stmt-sequence end //条件语句
| if exp then stmt-sequence else stmt-sequence end
repeat-stmt -> repeat stmt-sequence until exp //循环语句
assign-stmt -> id := exp //赋值语句
exp -> simple-exp compar-op simple-exp | simple-exp //算数表达式
compar-op -> < | =
simple-exp -> simple-exp add-op term | term
add-op -> + | -
term -> term mul-op factor | factor
mul-op -> * | /
factor -> ( exp ) | number | id

消左提左、构造first follow



基本思想

  • 为每个非终结符构造一个分析函数
  • 用前看符号指导产生式规则的选择

第一点简单来说就是A -> Bc B -> d
构造函数A(),B()
第二点即是说会用到first(A)和first(B) 即上图中的红色部分

python构造源码

对于文法来说分三种情况

  1. A -> B C
    没有其他的终结符和|,则直接调用两个产生式右部的非终结符函数

如: stmt-sequence -> statement ST

  1. A -> B | C
    存在 | ,则需要看A的first,| 等价于if-else,所以需要看first(A)的结果去分类判断该调用哪个非终结符函数,同时,这里需要putback,因为这个token是多读的,需要将指针调回去

如:statement -> if-stmt | repeat-stmt | assign-stmt

  1. A -> B |
    存在 空,则需要回溯,因为A可以在此不做任何事情,因而读取的token不满足first(B)时,则同样需要putback,将指针倒回去重新读取token

如:ST -> ;statement ST |

主要函数

  • 基本的函数定义
    init初始化函数,得到已经特意写好的token流,指针位置初始化为0
    get_next_token 得到下一个token
    put_token_back 回溯上一个token
  • main函数
    预置好了token流,用空格分开,因为上面init是根据空格切开为数组的
    匹配过程中如果有错误,会直接抛出异常,则程序是不会走到最后的print的,故输出匹配成功了则是匹配无误
  • 非终结符函数


运行结果


故意改错语法 tiny语言赋值语法为’ := ’ 而非’ = ’

完整源码:parseTINY

TINY语言采用递归下降分析法编写语法分析程序的更多相关文章

  1. 编译原理-递归下降分析法 c程序部分的分析

    实验三 语法分析程序实验 专业 商软2班   姓名 黄仲浩  学号 201506110166 一. 实验目的      编制一个部分文法分析程序. 二. 实验内容和要求 输入:源程序字符串 输出:正确 ...

  2. Tiny语法分析器(递归下降分析法实现)

    递归规约规则是这样的 program→stmt-sequence stmt-sequence→stmt-sequence;statement|statement statement→if-stmt|r ...

  3. 编译原理 #02# 简易递归下降分析程序(js实现)

    // 实验存档 截图: 代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"&g ...

  4. 作业十一——LL(1)文法的判断,递归下降分析程序

    作业十一——LL(1)文法的判断,递归下降分析程序 判断是否为LL(1)文法 选取有多个产生式的求select,只有一条产生式的无需求select 同一个非终结符之间求交集,全部判断为空后则为LL(1 ...

  5. 递归下降和LL(1)语法分析

    什么是自顶向下分析法 在语法分析过程中一般有两种语法分析方法,自顶向下和自底向上,递归下降分析和LL(1)都属于是自顶向下的语法分析 自顶向下分析法的过程就像从第一个非终结符作为根节点开始根据产生式进 ...

  6. 十一次作业——LL(1)文法的判断,递归下降分析程序

    1. 文法 G(S): (1)S -> AB (2)A ->Da|ε (3)B -> cC (4)C -> aADC |ε (5)D -> b|ε 验证文法 G(S)是不 ...

  7. LL(1)文法的判断,递归下降分析程序

    1. 文法 G(S): (1)S -> AB (2)A ->Da | ε (3)B -> cC (4)C -> aADC | ε (5)D -> b | ε 验证文法 G ...

  8. 编译原理之LL(1)文法的判断,递归下降分析程序

    1. 文法 G(S): (1)S -> AB (2)A ->Da|ε (3)B -> cC (4)C -> aADC |ε (5)D -> b|ε 验证文法 G(S)是不 ...

  9. 第十一次作业 LL(1)文法的判断,递归下降分析程序

    1. 文法 G(S): (1)S -> AB (2)A ->Da|ε (3)B -> cC (4)C -> aADC |ε (5)D -> b|ε 验证文法 G(S)是不 ...

随机推荐

  1. [链表]LeetCode 25 K组一个翻转链表

    LeetCode 25 k组一个翻转链表 TITLE 示例 1: 输入:head = [1,2,3,4,5], k = 2 输出:[2,1,4,3,5] 示例 2: 输入:head = [1,2,3, ...

  2. 前端面试题(js)

    js 基础面试题 css 面试题 js 面试题 JavaScript 有几种类型的值?,你能画一下他们的内存图吗 原始数据类型(Undefined,Null,Boolean,Number.String ...

  3. spinlock 设计的初衷,当只有单核时是否还需要锁

    自旋锁,的设计初衷是什么,是为了解决什么问题.如果只有一个cpu,并且是单核,那是否还需要用到自旋锁.

  4. vs 2019 社区版 .net core 5.0 之 .net core ef 迁移问题方案

    问题一:Add-Migration 时出现 此类问题一般都是模型类主键标识问题增加KEY即可解决 报错: The entity type 'xxxx' requires a primary key t ...

  5. Java基础 - 泛型详解

    2022-03-24 09:55:06 @GhostFace 泛型 什么是泛型? 来自博客 Java泛型这个特性是从JDK 1.5才开始加入的,因此为了兼容之前的版本,Java泛型的实现采取了&quo ...

  6. JavaScript 02 运算符,分支结构

    一元换算符 字符串类型 对于字符串,来说自增或自减会自动进行类型转换 1.var str = '10' 自动转换 从string转为number 2.str++ NaN 对于转化不成功的string类 ...

  7. dev编译器兼容设置及字符串的识别问题

    #include<bits/stdc++.h> using namespace std; bool cmp(char a,char b) { return a>b; } //int ...

  8. 保姆教程系列二、Nacos实现注册中心

    前言: 请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i 上篇我们介绍到  保姆教程系列一.Linux搭建Nacos 注册中心原理 一.环境准备 Java版本:1.8+   (Linux ce ...

  9. eureka自我保护机制是什么?

    当Eureka Server 节点在短时间内丢失了过多实例的连接时(比如网络故障或频繁启动关闭客户端)节点会进入自我保护模式,保护注册信息,不再删除注册数据,故障恢复时,自动退出自我保护模式.

  10. 什么是 AOP?

    在软件开发过程中,跨越应用程序多个点的功能称为交叉问题.这些交叉问题与 应用程序的主要业务逻辑不同.因此,将这些横切关注与业务逻辑分开是面向方 面编程(AOP)的地方.