作为学习龙书前4章一个总结,做一个计算器,支持+-*/(),*/优先,lex采用flex2.5.37,yacc采用bison2.7

最后的效果是可以连续输入表达式进行计算,比如3.2+5.3*(6.2+3.3)

首先构建可以单独运行的可以识别浮点数的词法分析器和可以处理单个数字的语法分析器,然后进行修改并将两者结合起来

首先构建独立词法分析器,参考龙书中图4-60

%{
#include "stdio.h"
float yylval;
float NUMBER;
%}number  [0-9]+\.?|[0-9]*\.[0-9]+
%%
[ ]     { /* skip blanks */ }
{number}        { sscanf(yytext, "%f", &yylval);return NUMBER; }
\n|.    { return yytext[0]; }
%%int yywrap()
{return 1;
}void main()
{yylex();printf("output:%f\n", yylval);
}

然后构建词法分析器

%{
#include <ctype.h>
%}%token NUMBER%%
line    : expr '\n'     { printf("output:%f\n", $1); };
expr    : expr '+' term { $$ = $1 + $3; printf("expr%f=%f+%f\n", $$,$1,$3); }| expr '-' term { $$ = $1 - $3; printf("expr%f=%f-%f\n", $$,$1,$3); }| term { $$ = $1; printf("expr=%f\n", $1); };
term    : term '*' factor { $$ = $1 * $3; printf("term%f=%f*%f\n", $$,$1,$3); }| term '/' factor { $$ = $1 / $3;  printf("term%f=%f/%f\n", $$,$1,$3); }| factor        { $$ = $1; printf("factor:%f\n", $1); };
factor  : '(' expr ')'  { $$ = $2;  printf("factor(%f)\n", $2);}| NUMBER        { $$ = $1; printf("number:%f\n", $1); };
%%
yylex() {int c;c = getchar();if (isdigit(c)){yylval = c-'0';return NUMBER;}return c;
}
void yyerror(char *s)
{printf("%s\n", s);
}

将二者结合起来发现词法分析器不能正确识别浮点数,原因是YACC默认为int,修改即可:#define YYSTYPE float

first.l

%{
%}
number  [0-9]+
%%
[ ]     { /* skip blanks */ }
{number}        { yylval = atoi(yytext);return NUMBER; }
\n|.    { return yytext[0]; }
%%int yywrap()
{return 1;
}

second.y

%{
#define YYSTYPE float
#include <ctype.h>
%}%token NUMBER%%
line    : expr '\n'     { printf("output:%d\n", $1); };
expr    : expr '+' term { $$ = $1 + $3; printf("expr%d=%d+%d\n", $$,$1,$3); }| expr '-' term { $$ = $1 - $3; printf("expr%d=%d-%d\n", $$,$1,$3); }| term { $$ = $1; printf("expr=%d\n", $1); };
term    : term '*' factor { $$ = $1 * $3; printf("term%d=%d*%d\n", $$,$1,$3); }| term '/' factor { $$ = $1 / $3;  printf("term%d=%d/%d\n", $$,$1,$3); }| factor        { $$ = $1; printf("factor:%d\n", $1); };
factor  : '(' expr ')'  { $$ = $2;  printf("factor(%d)\n", $2);}| NUMBER        { $$ = $1; printf("number:%d\n", $1); };
%%
#include "lex.yy.c"
void yyerror(char *s)
{printf("%s\n", s);
}

第一行 line : expr '\n'是为了让\n作为一个匹配的结束,否则只能计算一次

这样一个计算器就生成了,比自己手动写一个容易多了,当然要理解生成的代码还是很不容易。

关于lex代码阅读可以参考:Flex生成文件分析

bison代码阅读可以参考:Bison生成文件分析

#define YYSTYPE float

lex yacc 创建一个桌面计算器相关推荐

  1. C++程序设计语言(特别版) -- 一个桌面计算器

    前言 这里要介绍各种语句和表达式,将通过一个桌面计算器的程序做些事情,该计算器提供四种座位浮点数的中缀运算符的标准算术运算. 这个计算器由四个部分组成:一个分析器,一个输入函数,一个符号表和一个驱动程 ...

  2. 如何使用 Java AWT 创建一个简易计算器

    本文分享自华为云社区<手把手教你使用 Java AWT 创建一个简易计算器>,作者:海拥 . 关于AWT AWT (抽象窗口工具包)是一个有助于构建 GUI 的 API (图形用户界面)基 ...

  3. C++程序设计语言——一个桌面计算器示例

    目录 C++程序设计语言--一个桌面计算器示例 程序代码 C++程序设计语言--一个桌面计算器示例 C++程序设计语言一书中第10章 10.2节的桌面计算器示例. 程序代码 #include < ...

  4. linux如何给脚本等创建一个桌面启动图标

    本文主要讲述的是linux中如何给应用程序创建一个快速启动图标,话不多说,我们来看实际的操作步骤: 本文的实例是给celipse创建一个启动图标 1.我们需要通过下列命令,来创建一个启动的脚本: ge ...

  5. 编译原理-如何使用flex和yacc工具构造一个高级计算器

    Flex工具的使用方法 Lex 是一种生成扫描器的工具. Lex是Unix环境下非常著名的工具,主要功能是生成一个扫描器(Scanner)的C源码. 扫描器是一种识别文本中的词汇模式的程序. 这些词汇 ...

  6. 一、Qt初尝试,做一个QT计算器《QT 入门到实战》

    学习目标 了解 qt 的基本信息 了解 qt 的下载及安装 了解创建一个基本 qt 项目的流程 了解信号与槽 通过示例了解信号与槽的设置与编写 了解控件添加的方式 了解控件如何使用代码获取其文本 了解 ...

  7. ubuntu系统下创建软件桌面快捷方式

    默认情况下,ubuntu会将自动安装的软件快捷方式保存在/usr/share/applications目录下,如果我们要创建桌面快捷方式,只需要右键-复制-桌面 就Ok 上面的方法是通过系统自动安装软 ...

  8. 一个桌面弹幕软件,用来记单词刚刚好

    弹幕单词是一款桌面弹幕软件,它可以把词条以弹幕的形式呈现在桌面上,不管这个词条是英语单词还是中文成语,只要结合了相关资料,就非常方便的使用鼠标右键查看此弹幕的相关资料,下面我们来看看这个软件如何使用吧 ...

  9. 编译原理——C++版桌面计算器

    编译原理--C++版桌面计算器 系统描述 设计并实现一个桌面计算器,支持基本四则运算,关系运算,可编程运算 基本功能 (1)以命令行方式解析用户输入的表达式,计算并显示结果: (2)支持基本的整型和浮 ...

最新文章

  1. python语言培训班-深圳Python语言培训班
  2. python读取xml标注坐标_遍历文件 创建XML对象 方法 python解析XML文件 提取坐标计存入文件...
  3. linux学到了什么技术,Linux到底学什么?如何学?
  4. mysql绕过防火墙_[转载]使用sqlmap 绕过防火墙进行注入测试
  5. 链表node中保存的是什么_Redis源码解析一 --链表结构
  6. 光谱 波长_【第三课】红外光谱仪及其联用技术
  7. 递归遍历文件及子文件夹下的文件(该代码是复制过来修改过的,如果有侵作者权的话,请作者联系我,立即删除)...
  8. Web安全入门笔记-XSS
  9. 腾讯打免费牌争抢市场 马化腾表示QQ旋风免费
  10. Java CLH队列
  11. ISA Server 2006速战速决实验指南(7) 创建元素-网络对象
  12. 0930_C/C++笔试题_12:16道c语言面试【6/7】
  13. java url解码_URL的编码和解码
  14. 2019清华大学、中山大学、中传自主招生笔试面试真题
  15. Android获取设备的IP地址的两种方法
  16. android 7 语音助手,语音助手横评:iPhone 大战 Android 旗舰,谁更好用?
  17. Recoil - Facebook 官方 React 状态管理器
  18. 昆石VOS3000/VOS2009 Web手机管理说明
  19. 图解网络:组建一个网络需要哪些网络设备和安全设备
  20. 无监督学习-自编码器-补充|深度学习(李宏毅)(二十)

热门文章

  1. Java程序经编译后会产生什么
  2. S7-1200PLC与ABB机器人进行PROFINET通信的具体方法和步骤详解
  3. 八年级使用计算机的教案,八年级信息技术上册电子教案(全册)
  4. 【论坛转贴】IP spoof欺骗关于修改ip源向网页post的方法,伪造虚假IP来源!可用于群发发贴机拱贴机邮件EMail群发!!!!!!
  5. vscode 运行代码快捷键(Code Runner)
  6. php判断ip是否是内网/外网ip
  7. 第四章 治病法要(2)
  8. 关于 编译QT项目时报错: error: cannot find -lGL 的解决方法
  9. 操作系统原理(哈工大-李治军老师)操作系统引导
  10. 三维扫描在崇明花博会异形天桥及旋转楼梯测绘中的应用