最近在学习编译原理,利用flex和bison编写一个基于文本识别的简单计算器程序,参考《flex于bison》中内容,对程序进行一些简单的修改,加入Makefile。该计算器程序主要实现识别文本中的整数和运算符,进行加减乘除四则运算,暂不考虑括号对运算顺序的影响。
        flex用于词法分析器的构建,bison用于语法分析器构建,两者可以结合使用,利用bison生成源程序可以直接调用flex生成源程序中yylex()函数,提取标准输入文本中的目标字符,虽然main函数可以放到flex或bison的源码文件的用户自定义部分,但是不便于阅读和理解。因此将main函数单独放到一个cpp文件中,调用bison源码文件中的yyparse()函数对输入内容进行解析和处理。将计算器的运算实现放到bison源码的规则部分。
       创建test.l文件,编写词法分析规则(数字和符号识别)

%{#include <stdio.h>#include "test_yacc.h" //因为使用了bison在test_yacc.h中自动生成的token枚举extern int yylval; //yylval定义在bison库中
%}number [0-9]%%
{number}+ {yylval = atoi(yytext);printf("number: %d  ", yylval);return INT;
}"+" {printf("operator: +  ");return ADD;
}"-" {printf("operator: -  ");return SUB;
}"*" {printf("operator: *  ");return MUL;
}"/" {printf("operator: /  ");return DIV;
}\n { return EOL; }[ \t] {}. { //该条规则匹配除以上字符外的剩余字符,并且报错printf("error: input illegal character '%s'.\n", yytext);
}
%%void yyerror(const char *msg)
//该函数的重写可以放在任意位置,bison的yyparse()会调用该函数,需在.y文件中声明此函数
//传参必须为const,不然编译会报warning
{fprintf(stderr, "error: %s.\n", msg);
}

创建test.y文件,编写语法分析规则(计算器的运算处理),cal为创建的空规则,专门用于判断是否有换行,如果有换行,完成一次cal的规约,exp属性栈弹出,即exp清零。根据BNF表示方法,将首处理符号INT放在最底层规则,其次优先匹配乘除法,在处理乘除法之后再匹配加减法。

%{#include <stdio.h>extern int yylex();extern void yyerror(const char *);
%}%token INT
%token ADD SUB MUL DIV
%token EOL
%%
cal : | cal exp EOL { printf("\n<archerfoo> caculation result: %d\n", $2); };exp : factor| exp ADD factor { $$ = $1 + $3; } | exp SUB factor { $$ = $1 - $3; } ;factor : term| factor MUL term { $$ = $1 * $3; } | factor DIV term { $$ = $1 / $3; } ;term : INT;
%%

创建testMain.cpp,编写main函数内容:

#include <stdio.h>//extern int yylex();
extern int yyparse();int main(int argc, char ** args)
{//yylex(); yyparse(); //调用bison的yyparse()函数return 0;
}

编写编译Makefile脚本

ECHO = echo
CXX  = g++TARGET = ./testDemoLIBS   = -lflCFLAGS = -Wall
CFLAGS += -std=c++11OBJECTS =  testMain.o
OBJECTS += test_yacc.o
OBJECTS += test_lex.o$(TARGET) : $(OBJECTS)$(CXX) -o $(TARGET) $(OBJECTS) $(LIBS) $(CFLAGS) .cpp.o :$(CXX) -o $@ -c $<#生成test_yacc.cpp、test_yacc.h
#test_yacc.h会生成token的相关枚举
test_yacc.cpp : test.ybison -d $< -b test_yaccmv test_yacc.tab.c test_yacc.cppmv test_yacc.tab.h test_yacc.h#生成test_lex.cpp
test_lex.cpp : test.lflex -o $@ $<.PHONY : cleanclean:rm $(OBJECTS) $(TARGET) test_yacc.h test_yacc.cpp test_lex.cpp

编译:

yylex()返回记号token标志,标志0-255被保留作为字符值,可以自己定义token标志的值,一般由bison产生的token标志默认从258开始。本例中,由bison生成的test_yacc.h文件,其中token枚举定义:

调试结果:

flex和bison实例分析相关推荐

  1. 超详细的flex弹性布局+实例分析

    1.基本概念 什么是flex? flex全称是FlexibleBox,即弹性盒子,用来进行弹性布局,弹性布局也是目前前端应用最广的布局之一. flex布局的优点,为什么要用flex布局? 1.可以为盒 ...

  2. gpgpu-sim卡分配程序设计实例分析

    gpgpu-sim卡分配程序设计实例分析 运行代码地址:https://github.com/gpgpu-sim/gpgpu-sim_distribution 一.概述 此文件包含有关安装.生成和运行 ...

  3. 自制编译器学习3:Flex和Bison简介

    Flex和Bison安装 Ubuntu环境下直接安装即可: apt-get install flex bison 第一个Flex程序 首先给出代码(fb1-1.l): /* Companion sou ...

  4. flex与bison

    flex与bison flex与bison简介 词法分析与语法分析 flex用作词法分析,而bison用作语法分析.词法分析把输入分解成一个个有意义的词块,称作token:语法分析则确定这些词块彼此之 ...

  5. 编译器(汇编器)开发工具Flex和Bison的使用方法之Flex

    点击打开链接 编译器和汇编器在工作过程中,往往完成如下的任务: (1) 读取源代码并且获得程序的结构描述: (2) 分析程序结构,并且生成相应的目标代码. Flex和Bison就是为可以帮助完成以上任 ...

  6. centos7下安装flex,bison

    centos7下安装flex,bison 1,修改镜像源为国内镜像源,比如阿里云 (1)首先备份系统自带yum源配置文件/etc/yum.repos.d/CentOS-Base.repo [root@ ...

  7. 手把手教程-lex与yacc/flex与bison入门(一)(使用windows环境)

    前言 1.文章诞生的契机 在计算机学习中,我们有时可能会想到自制一门属于自己的编程语言,此时选择lex与yacc来生成词法分析器与语法分析器是非常不错的选择.然而,这两个工具虽然用起来简单,但对于新手 ...

  8. lex(flex)yacc(bison)

    初始配置 文法分析用Flex(Lex):将数据分隔成一个个的标记token (标示符identifiers,关键字keywords,数字numbers, 中括号brackets, 大括号braces, ...

  9. python多功能电子钟_python gui - PyQt4 精彩实例分析之电子钟

    PyQt4 精彩实例分析之电子钟,当然在写实例之前要先安装PyQt4模块.from PyQt4.QtGui import * from PyQt4.QtCore import * import sys ...

最新文章

  1. 用Servlet获取表单数据
  2. 【集合论】关系闭包 ( 关系闭包相关定理 )
  3. Lambda表达式替代匿名方法
  4. How is XSRF token retrieved from backend
  5. tsp 选边 matlab,【转载】蚁群算法TSP(旅行商问题)通用matlab程序
  6. python知识点汇总_Python知识点总结大全(一)
  7. java listen_JavaWeb之Filter、Listener
  8. javascript控制台_如何使您JavaScript控制台静音
  9. PHP新手之学习类与对象(4)
  10. python输出缓冲区的问题
  11. appium的滑动操作总结
  12. 2022年全球及中国MICC电缆行业运行战略规划与未来投资策略分析报告
  13. M1 外接2K显示器开启HiDPI 的解决方案
  14. Python——读取xlsx格式的Excel表格
  15. 4、Android 手机端进行实时目标检测,并使用FFMPEG将检测的视频流推到服务器显示
  16. 通用流量录制回放工具 jvm-sandbox-repeater 尝鲜 (三)—— repeater plugin 开发
  17. 用java代码写的段子_网上调侃程序员的段子
  18. quill.js官方文档(六)【增量Delta】
  19. Java实现远程桌面连接
  20. 差分龄期(age of diff)对RTK定位精度的影响分析(包含RTKLIB实际测试)

热门文章

  1. CVPR2020:基于自适应采样的非局部神经网络鲁棒点云处理(PointASNL)
  2. Linux系统快速安装JDK
  3. 高级数据结构讲解与案例分析
  4. 【嵌入式】openmv与stm32的串口通信
  5. [JS][C++]两题斐波那契数列:上台阶、triangle
  6. C++ set 的使用
  7. Make sure no other Soong process is using it
  8. Android 绘制同心圆 (2个圆叠加在一起)
  9. RecylerView为item添加点击事件
  10. iOS 开发经验总结