flex&bison编写语法分析器

2023-10-28

使用flex和bison,对c语言代码块进行词法分析,识别词法错误,按照c—语法规则进行文法分析,并形成c语言代码块的语法树(syntax tree),并将语法树按照特定的格式打印出来。

如何编译

两种方法:
(1)使用make命令:先将要执行的所有命令写入到Makefile文件中,然后执行make命令,这就相当于将Makefile中的所有命令都执行完毕了,在终端可以清楚地看到系统每执行一条命令的结果,如果有错或者有警告都会输出。make执行完之后,就生成a.out文件,使用cat filename|./a.out就可以对filename中的文件就行语义分析了。
当文件有更新时,只需要执行以下make即可。
(2)这种是最笨的方法,就是不写Makefile文件,每次都是逐条去执行编译命令,文件有更新之后也要逐条执行,这种效率是最低的。make命令的出现就是为了提高编译效率的,有关make的知识点可以自行百度。

下面是第一种编译方法的具体过程:

【实验程序】

0,Makefile——编译文件

程序总共包含4个文件gramtree_v1.h gramtree_v1.c gramtree.l gramtree_v1.y
gramtree_v1.h gramtree_v1.c定义和实现了创建语法树和遍历语法树的函数
gramtree.l是flex词法分析模块
gramtree_v1.y是bison语法分析模块

编译时使用Makefile文件,编写文件内容,vim Makefile

result:gramtree_v1.y gramtree.l gramtree_v1.h
    bison -d  gramtree_v1.y
    flex gramtree.l
    gcc gramtree_v1.tab.c lex.yy.c gramtree_v1.c 

编译过程如下:

[root@localhost flex]# make
[root@localhost flex]# cat input3.c|./a.out 

先执行make命令,这代表Makefile的编译步骤全都执行完毕了。然后使用
cat filename|./a.out就可以对filename中的代码进行语法分析,打印出语法树。

gramtree_v1.h—定义创建和遍历语法树函数的头文件

/*
*Name:gramtree_v1.h
*Author:WangLin
*Created on:2015-10-03
*Function:定义语法树结点结构体&变长参数构造树&遍历树函数
*/
/*来自于词法分析器*/
extern int yylineno;//行号
extern char* yytext;//词
void yyerror(char *s,...);//错误处理函数

/*抽象语法树的结点*/
struct ast
{
    int line; //行号
    char* name;//语法单元的名字
    struct ast *l;//左孩子
    struct ast *r;//右孩子
    union//共用体用来存放ID/TYPE/INTEGER/FLOAT结点的值
    {
    char* idtype;
    int intgr;
    float flt;
    };
};

/*构造抽象语法树,变长参数,name:语法单元名字;num:变长参数中语法结点个数*/
struct ast *newast(char* name,int num,...);

/*遍历抽象语法树,level为树的层数*/
void eval(struct ast*,int level);

gramtree_v1.c——实现创建和遍历语法树函数

/*
*Name:gramtree_v1.c
*Author:WangLin
*Created on:2015-10-03
*Function:实现变长参数构造树&遍历树函数&错误处理函数,yyparse()启动文法分析
*/
# include<stdio.h>
# include<stdlib.h>
# include<stdarg.h>//变长参数函数所需的头文件
# include"gramtree_v1.h"
int i;
struct ast *newast(char* name,int num,...)//抽象语法树建立
{
    va_list valist; //定义变长参数列表
    struct ast *a=(struct ast*)malloc(sizeof(struct ast));//新生成的父节点
    struct ast *temp=(struct ast*)malloc(sizeof(struct ast));
    if(!a) 
    {
        yyerror("out of space");
        exit(0);
    }
    a->name=name;//语法单元名字
    va_start(valist,num);//初始化变长参数为num后的参数

    if(num>0)//num>0为非终结符:变长参数均为语法树结点,孩子兄弟表示法
    {
        temp=va_arg(valist, struct ast*);//取变长参数列表中的第一个结点设为a的左孩子
        a->l=temp;
        a->line=temp->line;//父节点a的行号等于左孩子的行号

        if(num>=2) //可以规约到a的语法单元>=2
        {
            for(i=0; i<num-1; ++i)//取变长参数列表中的剩余结点,依次设置成兄弟结点
            {
                temp->r=va_arg(valist,struct ast*);
                temp=temp->r;
            }
        }
    }
    else //num==0为终结符或产生空的语法单元:第1个变长参数表示行号,产生空的语法单元行号为-1。
    {
        int t=va_arg(valist, int); //取第1个变长参数
        a->line=t;
        if((!strcmp(a->name,"ID"))||(!strcmp(a->name,"TYPE")))//"ID,TYPE,INTEGER,借助union保存yytext的值
        {
  char*t;t=(char*)malloc(sizeof(char* )*40);strcpy(t,yytext);a->idtype=t;}
        else if(!strcmp(a->name,"INTEGER")) {a->intgr=atoi(yytext);}
        else {}
    }
    return a;
}

void eval(struct ast *a,int level)//先序遍历抽象语法树
{
    if(a!=NULL)
    {
        for(i=0; i<level; ++i)//孩子结点相对父节点缩进2个空格
            printf("  ");
        if(a->line!=-1){ //产生空的语法单元不需要打印信息
            printf("%s ",a->name);//打印语法单元名字,ID/TYPE/INTEGER要打印yytext的值
            if((!strcmp(a->name,"ID"))||(!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

flex&bison编写语法分析器 的相关文章

  • sql联合顺序

    我有一张桌子 上面有学生的姓名和身高 我想要一个查询 按字母顺序对身高高于 150 厘米的学生进行排序 对身高低于 150 厘米的学生按姓名降序排列 像这样的东西 select from students where height gt 1
  • MySQL DELETE FROM 与 IN 条件的 UNION 子查询

    我遇到了一个奇怪的 SQL 错误 最后一个查询不起作用 当然 我可以将 DELETE 拆分为三个查询 但我真的想知道为什么 MySQL 不允许我这样做 一个小例子 SELECT id FROM stairs WHERE building 1
  • 我的 Flex 文件输出错误

    我编写了一个 l 文件并希望输出 c17 isc 中的内容 但有一个错误我不知道为什么 我已经给出了我打算读取的文件 flex文件和执行结果 这是 c17 isc 文件 内容的意思是 number gate name gate type o
  • 无法配置 CMake 来查找 Bison 的 Homebrew 安装版本

    我正在运行 macOS 10 14 并且安装了bison版本 3 2 与brew 但它拒绝链接 brew link bison force Warning Refusing to link macOS provided software b
  • 使用 Flex 和 Bison 编译时未定义对“_yyerror”的引用

    我正在尝试为迷你 Pascal 语言制作一个编译器 我为此使用了 Flex 和 Bison 并且出现了这个错误 我的 Flex 文件 include y tab h include
  • 从flex+bison输出AST到main.cpp

    免责声明 虽然我已经完成了本教程 但我是一名 flex bison 菜鸟 http ds9a nl lex yacc cvs lex yacc howto html http ds9a nl lex yacc cvs lex yacc ho
  • 通过交集和并集组合 NSArray

    我有两个 NSArrays A 和 B 它们共享一些共同的元素 例如 A 1 2 3 4 5 B 4 5 6 7 我想创建一个新的 NSArray 其中包含两个 NSArray 之间常见的内容 并与第二个 NSArray 的内容相连接 同时
  • 如何将 lex 文件中的 yytext 传递给 yacc?

    请我面临一个简单的问题 这就是问题 在我的 lex 文件中 我有类似的内容 char ptr String name BEGIN sName
  • Postgresql UNION 花费的时间是运行单个查询的 10 倍

    我试图获取 postgresql 中两个几乎相同的表之间的差异 我当前运行的查询是 SELECT FROM tableA EXCEPT SELECT FROM tableB and SELECT FROM tableB EXCEPT SEL
  • vc++下编译bison和flex程序时unistd.h相关困难

    我正在使用 bison flex 通过 cygwin 下载 和 vc 当我编译程序时 出现错误 fatal error C1083 Cannot open include file unistd h No such file or dire
  • Flex 和 Bison 彼此需要什么?

    当 Flex 和 Bison 一起使用时 为什么 Flex 文件需要 includebison 创建的 C 头文件 编译需要 bison 和 flex 创建的 C 源文件 bison 和 flex 创建的 C 源文件相互需要什么 bison
  • Mysql 联合时间 V.S.一对一单独查询[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 如果我有 n 个查询 q1 q2 q
  • MYSQL:使用 union 将两个表合并为一个表

    我必须用另外两个表制作一个表 并使用联合 有效的查询是 SELECT FROM tabel1 UNION SELECT FROM tabel2 现在我要做的就是将此结果 数据 放入表3 我已经拥有的表 其列与表1和表2中的列相同 谁能帮我
  • 如何使大循环的联合范围更快

    我有一个子程序 在循环中进行大约 5000 次迭代后 它变得非常慢 否则很快 Windows 8 1 专业版 64 位 Excel 2013 15 0 4701 1001 MSO 15 0 4701 1000 64 位 Sub UnionS
  • 在联合上分配泛型类型

    TS 中有没有办法通过联合 分布 泛型类型 type Container a value A type Containers a
  • 具有混合成员类型的通用 TypeScript 接口

    对于几个 HTML 表单 我想配置输入并处理它们的值 我的类型具有以下结构 您可以将其复制到 TypeScript Playgroundhttp www typescriptlang org play http www typescript
  • Yacc/Bison:伪变量($$、$1、$2、..)以及如何使用 printf 打印它们

    我有一个用 flex 编写的词法分析器 它将标记传递给用 bison 编写的解析器 以下是我的词法分析器的一小部分 ID a z a z0 9 rule printf A rule s n yytext return RULE ID pri
  • 对“yylex()”的未定义引用

    我正在尝试使用 flex 和 bison 创建一种简单的脚本语言 现在 我只是想让计算器工作 但我无法编译它 当我运行这个 makefile 时 OBJECTS hug tab o hug yy o PROGRAM hug exe CPP
  • mysql 在 sum() 函数上使用 concat,例如 concat(sum(col1),"%")

    我正在尝试合并多个查询 但其中一个查询使用 sum 当我尝试在此列上应用 concat 时 我得到不需要的 blob 结果 我如何在聚合列上应用 concat 和 union 我期待这个结果 SELECT row 1 col1 UNION
  • 有没有办法改变野牛的弹性启动状态?

    我在词法分析器中定义了不同的状态 这些状态的变化不取决于令牌 而是取决于令牌序列 类似于模板引擎的工作方式 我可以定义更长的标记 但我更喜欢这种方法 您可以将一个函数粘贴到使用 BEGIN 宏的 l 文件的第三部分中 然后从您的 bison

随机推荐

  • 在ESXi界面给虚拟机配的内核数与虚机内任务管理器显示数不一致

    source esxi6 7设备管理器中的cpu核数和任务管理器中的不一致 esxi吧 百度贴吧 ESXi里给某台win10虚机配置了16核cpu 但在此虚机里面的任务管理器里却只看到2个核心 原因在下图 把CPU和和每个插槽内核数改成一样
  • JavaSE学习 day01

    今天是学习JavaSE的第一天 首先 我先初识了Java 了解了学习目标 知道了什么是程序 什么是Java 为什么学习Java 然后 学习了搭建Java开发环境 1 安装JDK 2 配置环境变量 这里要注意 JDK java开发工具包 JR
  • JS中的函数-内部函数,子调用函数和返回值为函数的函数

    自调用函数 Self invoking Functions 自调用函数也是匿名函数的一种表现形式 这个函数在定义之后 直接调用 如下 function alert haha 看起来还挺怪异 不过确实很简单 自调用函数很方便使用 可以不用定义
  • 多个Node.js版本之间切换

    本篇文章会讲windows和Mac系统下实现多个node js版本之间的切换 1 windows下采用nvm nvm window 2 Mac下采用nvm和n 注 window和mac下的nvm地址是不一样的 一 windows系统 什么是
  • JDK 8 / JDK 1.8 压缩包

    文章大概 因为JDK8在官网是直接的一个exe可运行程序 并没有压缩包 而网络上有别人准备的压缩包 看到是某度盘直接放弃 所以这篇文章教大家自己来搞一个JDK8的压缩包文件 开始操作 在操作之前 你需要去Java Downloads Ora
  • 对象转JSONObject——字段空值处理方法

  • uniapp 发布微信小程序分包

    1 进入下列文件 进入 unpackage dist build mp weixin app json pages pages index index pages login login pages views WearCutData We
  • 十个漂亮的数学定理赏析

    原地址 十个漂亮的数学定理赏析 Beauty is the first test there is no permanent place in the world for ugly mathematics G H Hardy 科学家研究自然
  • MYSQL--基础--11--join理解

    MYSQL 基础 11 join理解 1 数据初始化 SET FOREIGN KEY CHECKS 0 Table structure for course DROP TABLE IF EXISTS course CREATE TABLE
  • GPT,GPT-2,GPT-3

    视频讲解 GPT GPT 2 GPT 3 论文精读 论文精读 哔哩哔哩 bilibili 论文链接 GPT https www cs ubc ca amuham01 LING530 papers radford2018improving p
  • JUC学习系列八(信号量 Semaphore)

    一个计数信号量 从概念上讲 信号量维护了一个许可集 Semaphore 通常用于限制可以访问某些资源 物理或逻辑的 的线程数目 通常 应该将用于控制资源访问的信号量初始化为公平的 以确保所有线程都可访问资源 为其他的种类的同步控制使用信号量
  • 学习 Python 数据结构与算法,这是我见过最友好的教程

    Pascal 之父 Nicklaus Wirth 曾说 程序 数据结构 算法 在 算法 第4版 中 作者也说过 数据结构和算法的学习是计算机科学和软件工程领域的基础 它们对于解决实际问题和优化程序性能至关重要 数据结构与算法的重要性不言而喻
  • 资源共享——《嵌入式Linux应用开发完全手册》韦东山 PDF电子档下载

    嵌入式Linux应用开发完全手册 经典的Linux驱动入门书籍
  • 学习笔记-架构的演进之k8s的存储扩展架构-3月day10

    文章目录 前言 Kubernetes 存储架构 FlexVolume 与 CSI FlexVolume CSI 从 In Tree 到 Out of Tree 附 前言 容器存储具有很强的多样性 如何对接后端实际的存储系统 并且完全发挥出它
  • 2022CTFSHOW菜狗杯部分MISC(一)

    11 14WP MISC 迷之栅栏 ctfshow 010editor文件比较 解压附件得到2张图 用010打开 使用比较文件功能 查看两个图片的十六进制字符串不同的部分 cfhwfaab2cb4af5a5820 tso 06071f997
  • 领鹿谷资讯:量化的收益,让你意想不到

    从事这行业久了 总是会被问及到的众多问题 也都是千篇一律的 比如 我该怎么做 学什么 怎样才能盈利 你们是用什么方法 可以带着我做吗 为什么我总选不对品种 方向 是不是你们能预测行情 你们有什么消息 能不能下次也告诉我 其实每一个阶段的投资
  • 解决Windows中d3dcompiler_39.dll缺少问题

    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题 如果是新手第一时间会认为是软件或游戏出错了 其实并不是这样 其主要原因就是你电脑系统的该dll文件丢失了或者损坏了 这时你只需下载这个d3dcompiler 39 dll文件进行安装
  • python判断数是整数还是小数

    a 98 5 s str a split if float s 1 0 print 整数 else print 小数 数转化为字符串并通过split在小数点处分割形成一个列表 转化为浮点型后我们只需要判断s 1 是否为0就可以看出a是否为小
  • Springboot测试类之@RunWith注解

    runWith注解作用 RunWith就是一个运行器 RunWith JUnit4 class 就是指用JUnit4来运行 RunWith SpringJUnit4ClassRunner class 让测试运行于Spring测试环 境 以便
  • flex&bison编写语法分析器

    使用flex和bison 对c语言代码块进行词法分析 识别词法错误 按照c 语法规则进行文法分析 并形成c语言代码块的语法树 syntax tree 并将语法树按照特定的格式打印出来 如何编译 两种方法 1 使用make命令 先将要执行的所