lemon源码基本概念整理

2023-05-16

1 数据结构

1.1 字符串存储

定义一个x1a的全局变量,存放.y文件经过词法分析器分割出来的字符串

struct s_x1 {
  int size;               /* The number of available slots. */
                          /*   Must be a power of 2 greater than or */
                          /*   equal to 1 */
  int count;              /* Number of currently slots filled */
  struct s_x1node *tbl;  /* The data stored here */
  struct s_x1node **ht;  /* Hash table for lookups */
};

/* There is one instance of this structure for every data element
** in an associative array of type "x1".
*/
typedef struct s_x1node {
  const char *data;        /* The data */
  struct s_x1node *next;   /* Next entry with the same hash */
  struct s_x1node **from;  /* Previous link */
} x1node;

/* There is only one instance of the array, which is the following */
static struct s_x1 *x1a;

tbl是一个存放data的数组,ht是一个哈希数组,存放着tbl数据的地址,如果哈希表的key值相同,则插入到一个双向链表里,下面是往容器里存数据的代码
在这里插入图片描述

1.2 符号

符号用symbol结构体,即终结符和非终结符,存放在x2a容器里,结构和上面一样,代码在Symbol_insert里

1.3 rule

rule就是.y文件中的各条产生式,如下图
在这里插入图片描述
rule结构体如下
在这里插入图片描述
主要关注下nextlhs,这个链表把左边具有相同symbol的产生式链接在一起

1.4 config

这个结构就是把rule和要移进前的*再组成要给结构体,所有config放在一个x3a的容器里
在这里插入图片描述

1.5 state

state就是把config和action再整合成一个结构体,数据放在x4a容器,其中config包括基本项目和全部项目
在这里插入图片描述
直观的感受可以看.out文件
在这里插入图片描述
其中红框是是state,绿框和黑框都是config存放再cfg链表里,其中黑框是基本项目,存放再bp链表里

2 状态生成

入口函数在FindStates,先生成基本状态
在这里插入图片描述
这条产生式一般是第一条,就是最后归约的那一条

program ::= expr(A) TK_SEM(B).

然后就是getstate和buildshifts的相互递归调用,如果状态不存在的话则生成一个新状态,以1.5为例,传入的是黑框bp,然后调用Configlist_closure(lemp);生成所有绿框,最后再整合成红框state
在这里插入图片描述
这里看一下Configlist_closure的代码,注意方框框起来的地方,不要把循环体搞错了
在这里插入图片描述
这个i=dot+1的循环是针对rp的而不是针对newrp的,我第一次看的时候就在这里搞混了

fplp的作用在计算follow集的时候会用到,newfp是由cfp派生出来的,cfp中如果出现sp右边是空串的情况,那么算newfp时也要把cfp的follow集算上,这个看下求follow集的代码就知道了
在这里插入图片描述

3 移进

移进时的代码是buildshifts,在getstate的最后时候调用,进入buildshifts的时候,已经生成了第1.5节红框框起来的所有项目,buildshifts里有两层循环,这个代码非常难以理解
在这里插入图片描述
为了清晰起见再把1.5节的这张图贴一下
在这里插入图片描述
外层for循环遍历所有的项目,先取出*右边的符号,以第1个为例取出expr,内层for循环找到所有右边是expr的项目,去转移到新状态,这里是转到状态10,我们看下状态10的项目,果然符合预期

State 10:
          expr ::= expr * TK_IMPL expr
      (3) expr ::= TK_NEG expr *

                     {default} reduce 3

也就是说通过两个for循环把*右边的符合进行分组划分新状态。

来看看bplp的作用,从下面代码可以看到,newcfg和bcfp具有相同的rp,只不过newcfg的dot多了1,也就是在newcfg->bplp中记录移进到newcfg的原始项目
在这里插入图片描述

先写这么多吧,有空再把动作相关代码整理一下

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

lemon源码基本概念整理 的相关文章

  • 求字符串中的最长回文子串

    方法一 xff08 暴力法 xff09 xff1a include lt stdio h gt include lt string h gt bool Palindrome const char str int start int end
  • 堆和栈访问效率哪个更高

    1 栈分配的软件优势 xff1a 栈分配算法简单 xff0c 所以高效 xff1b 堆分配算法相对比较复杂 栈分配的硬件优势 xff1a 主要两点 xff0c cache和内存映射 如果在 栈上分配小块内存 xff0c 因为cache和内存
  • C++ Primer学习-第15章 面向对象编程

    15 1 面向对象编程 xff1a 概述 在C 43 43 中 xff0c 基类必须指出希望派生类重新定义那些函数 xff0c 定义为virtual的函数是基类期待派生类重新定义的 xff0c 基类希望派生类继承的函数不能定义为学虚函数 1
  • Ubuntu18.04创建工作空间和功能包

    由于本人记性实在不好 xff0c 每次新建工作空间和功能包的时候都要重新百度 xff0c 因此就以这种方式记下来 xff0c 有错误的地方还请批评指正 1 创建工作空间catkin ws mkdir p catkin ws src 2 初始
  • 关于安装双系统Linux不能完整分区解决方法

    在我安装双系统win7 43 ubuntu 16 x x版本时 xff0c ubuntu 在安装过程中会检测到win7 系统磁盘使用情况 将ubuntu 安装在空闲硬盘位置时 xff0c 系统设置不能有4 个主分区 xff0c 所以在分区过
  • 彻底删除VM虚拟机手把手详细教学

    一 在彻底删除VMware之前我们应在服务中把VM的任务和进程全部中止 1 我们首先按windows键 输入 服务 我们打开服务 2 在服务中我们找到vm开头的服务 并右键停止这些服务 3 按ctrl 43 alt 43 del选择任务管理
  • Leetcode 常用函数总结(C语言版本)

    include lt stdio h gt include lt stdbool h gt include lt math h gt include lt ctype h gt include lt string h gt include
  • C++ map表的应用

    map表可以存储数据对应关系 include lt map gt include lt string gt include lt iostream gt using namespace std int main map lt int str
  • C++判断是否是IP地址

    判断是否是IP地址 bool isIPAddress const char s const char pChar bool rv 61 true int tmp1 tmp2 tmp3 tmp4 i while 1 i 61 sscanf s
  • ARDUSUB 浏览

    ArduSub is an advanced open source ROV AUV control system Overview ArduSub水下机器人的控制器是一个完整的开源解决方案 提供远程操作控制 通过智能潜水模式 和全自动的执
  • C++判断是否是纯数字

    C 43 43 判断是否是纯数字 bool isDigitStr const char cstr if NULL 61 61 cstr cstr 0 61 61 0 return false int len 61 strlen cstr i
  • 命里有时终须有,命里无时莫强求

    命里有时终须有 xff0c 命里无时莫强求 今天是2012年2月24号 xff0c 和我谈了3个多月的女生突然之间说我们之间不合适 xff0c 让我以后不要再去骚扰她 真心第一次体会到失恋的感觉 xff0c 同时打电话给我姐姐诉说了下 xf
  • 共享内存--函数

    共享内存允许两个不相关的进程访问同一个逻辑内存 共享内存是在两个正在运行的进程之间传递数据的一种非常有效的方式 大多数的共享内存的具体实现 xff0c 都把由不同进程之间共享的内存安排为同一段物理内存 共享内存是由IPC为进程创建的一个特殊
  • assert用法

    判断是否为真 include 34 stdio h 34 include lt string h gt include lt stdlib h gt define NDEBUG include lt assert h gt void mai
  • strcpy原型

    已知strcpy 函数的原型是 char strcpy char strDest const char strSrc 其中strDest 是目的字符串 xff0c strSrc 是源字符串 xff08 1 xff09 不调用C 43 43
  • new与delete正确用法

    说明 xff1a 推荐使用如下宏 xff0c 可以在一定程度上避免使用空指针 xff0c 野指针的问题 define HW NEW var classname do try var 61 new classname catch var 61

随机推荐