当前位置: 首页 > news >正文

flex与bison学习之简易计算器

第1章例子-简易计算器

简易计算器

代码(001_5_simple_calculator.y)

/* 简易计算器 */
%{
#include<stdio.h>
%}/* 定义记号 */
%token NUMBER
%token ADD SUB MUL DIV ABS
%token EOL
%%calclist: /* 空规则 */| calclist exp EOL { printf("=%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: NUMBER| ABS term { $$ = $2 >= 0 ? $2 : -$2; };
%%main(int argc, char **argv)
{yyparse();
}yyerror(char *s)
{fprintf(stderr, "error: %s\n", s);
}

代码(001_5_simple_calculator.l)

/* 简易计算器 */
%{
#include"001_5_simple_calculator.tab.h"
%}%%
"+"         { printf("%s", yytext); return ADD; }
"-"         { printf("%s", yytext); return SUB; }
"*"         { printf("%s", yytext); return MUL; }
"/"         { printf("%s", yytext); return DIV; }
"|"         { printf("%s", yytext); return ABS; }
[0-9]+      { yylval = atoi(yytext); printf("%s", yytext); return NUMBER; }
\n          { return EOL; }
[ \t]       { /* 忽略空白字符 */ }
.           { printf("Mystery character %c\n", *yytext); }%%

Makefile(001_5_simple_calculator.Makefile)

FILE_NAME = $(file_name)BISON_INPUT_FILE = $(FILE_NAME).y
BISON_OUTPUT_SRC_FILE = $(FILE_NAME).tab.c
BISON_OUTPUT_HEADER_FILE = $(FILE_NAME).tab.h
BISON_OBJECT_FILE = $(FILE_NAME).tab.o
BISON_CMD = bison
BISON_OUTPUT_FLAG = -o
BISON_DEFINE_FLAG = -dFLEX_INPUT_FILE = $(FILE_NAME).l
FLEX_OUTPUT_FILE = $(FILE_NAME).c
FLEX_CMD = flex
FLEX_FLAG = -oGCC_CMD = gcc
GCC_COMPILE_FLAG = -c
GCC_OUTPUT_FLAG = -o
GCC_LINK_FLAG = -lfl
GCC_OBJECT_FILE = $(FILE_NAME).oTARGET_FILE = $(FILE_NAME)all: clean bison_main flex_main gcc_mainbison_main: $(BISON_INPUT_FILE)$(BISON_CMD) $(BISON_OUTPUT_FLAG) $(BISON_OUTPUT_SRC_FILE) $(BISON_DEFINE_FLAG) $(BISON_INPUT_FILE)flex_main: $(FLEX_INPUT_FILE) $(BISON_OUTPUT_HEADER_FILE)$(FLEX_CMD) $(FLEX_FLAG) $(FLEX_OUTPUT_FILE) $(FLEX_INPUT_FILE)gcc_main: $(FLEX_OUTPUT_FILE)$(GCC_CMD) $(GCC_COMPILE_FLAG) $(BISON_OUTPUT_SRC_FILE) $(GCC_OUTPUT_FLAG) $(BISON_OBJECT_FILE)$(GCC_CMD) $(GCC_COMPILE_FLAG) $(FLEX_OUTPUT_FILE) $(GCC_OUTPUT_FLAG) $(GCC_OBJECT_FILE)$(GCC_CMD) $(BISON_OBJECT_FILE) $(GCC_OBJECT_FILE) $(GCC_LINK_FLAG) $(GCC_OUTPUT_FLAG) $(TARGET_FILE).PHONY: cleanclean:@rm -f $(BISON_OUTPUT_SRC_FILE)@rm -f $(BISON_OUTPUT_HEADER_FILE)@rm -f $(BISON_OBJECT_FILE)@rm -f $(FLEX_OUTPUT_FILE)@rm -f $(GCC_OBJECT_FILE)@rm -f $(TARGET_FILE)

编译指令

make -f 001_5_simple_calculator.Makefile file_name=001_5_simple_calculator

image-20260223184322052

测试指令

./001_5_simple_calculator
#输入以下信息,按Ctrl+D结束
2 + 3 * 4
2 * 3 + 4
20 / 4 - 2
20 - 4 / 2

image-20260223184506978

输出信息

image-20260223184535721


进阶计算器

增加对小括号以及注释的支持

代码(001_5_simple_calculator_plus.y)

/* 简易计算器 */
%{
#include<stdio.h>
%}/* 定义记号 */
%token NUMBER
%token ADD SUB MUL DIV ABS
%token OP CP
%token EOL
%%calclist: /* 空规则 */| calclist exp EOL { printf("=%d\n> ", $2); }| calclist EOL     { printf("> "); } /* 空行或注释 */;exp: factor| exp ADD exp    { $$ = $1 + $3; }| exp SUB factor { $$ = $1 - $3; }| exp ABS factor { $$ = $1 | $3; };factor: term| factor MUL term { $$ = $1 * $3; }| factor DIV term { $$ = $1 / $3; };term: NUMBER| ABS term  { $$ = $2 >= 0 ? $2 : -$2; }| OP exp CP { $$ = $2; };
%%main(int argc, char **argv)
{printf("> ");yyparse();
}yyerror(char *s)
{fprintf(stderr, "error: %s\n", s);
}

代码(001_5_simple_calculator_plus.l)

/* 简易计算器 */
%{
#include"001_5_simple_calculator_plus.tab.h"
%}%%
"+"         { printf("%s", yytext); return ADD; }
"-"         { printf("%s", yytext); return SUB; }
"*"         { printf("%s", yytext); return MUL; }
"/"         { printf("%s", yytext); return DIV; }
"|"         { printf("%s", yytext); return ABS; }
"("         { printf("%s", yytext); return OP; }
")"         { printf("%s", yytext); return CP; }
[0-9]+      { yylval = atoi(yytext); printf("%s", yytext); return NUMBER; }
\n          { return EOL; }
"//".*      { printf("original characters is: %s\n", yytext); }
[ \t]       { /* 忽略空白字符 */ }
.           { printf("Mystery character %c\n", *yytext); }%%

编译指令

make -f 001_5_simple_calculator.Makefile file_name=001_5_simple_calculator_plus

image-20260223191817831

测试指令

./001_5_simple_calculator_plus
#输入以下信息,按Ctrl+D结束
1 + 2 * ( 3 + 4 )
9 / ( 10 - 7 )

image-20260223191854502

输出信息

image-20260223191916694

http://www.jsqmd.com/news/405826/

相关文章:

  • flex与bison学习之一个简单的flex词法分析器
  • 2026年谷歌独立站多语种建站公司/服务商深度评测推荐:五强对比与中立对比助决策 - 深圳昊客网络
  • OpenClaw:2026年爆红的本地优先 AI 智能体引擎全解析
  • CrafterCMS 认证RCE漏洞利用 - Groovy沙箱逃逸 (CVE-2025-6384)
  • flex与bison学习之英式英语转换为美式英语
  • sql注入之文件读写
  • 从入门到实战:构建企业级交通实时路况监控系统的Python爬虫架构指南
  • DenseFramelet-DFD:基于密集框架小波变换和自适应阈值降噪的机械故障诊断方法(MATLAB)
  • 探索导弹六自由度运动模型及其MATLAB/Simulink实现
  • 总结了近期考MOS认证学员问的比较的问题
  • 题解:CF1210F2 Marek and Matching (hard version)
  • CF1322B
  • 2026年3月百度推广竞价广告开户代运营公司/服务商深度评测:深圳昊客网络 引领榜单 - 深圳昊客网络
  • 根脉与花开:AI元人文——中华文化思想在智能时代的原创性理论发展
  • AI Agent 框架探秘:拆解 OpenHands(7)--- Agent
  • 视频孪生之上:镜像视界矩阵视频融合驱动三维智慧交通升级——以重庆万州复杂立体交通场景为样本的统一空间坐标体系与跨摄像连续表达工程实践
  • 视频孪生之上 · 空间主权构建:镜像视界矩阵视频融合打造三维连续表达控制体系——基于统一坐标矩阵与动态修正机制的空间级主动感知与连续表达平台
  • 状压dp临行枚举类问题
  • 新的开始
  • CF1313D
  • 【Linux】进程地址空间的内核空间
  • [特殊字符] 基于YOLOv5/v8/v10的商超货架商品陈列面占比分析系统【完整源码+数据集】
  • JAVA WEB学习6
  • 【YOLO目标检测】基于YOLOv5/v8/v10的交通拥堵检测系统:从数据集构建到可视化界面全解析
  • 基于深度学习的鸡数量统计系统演示与介绍(YOLOv12/v11/v8/v5模型+Pyqt5界面+训练代码+数据集)
  • 算法题避坑指南:数组/循环范围的 `+1` 到底什么时候加?
  • Neo4j学习笔记1
  • upload
  • 2026年生产力革命:实测上百款AI工具后,这5款真正重塑了我的工作流
  • 别再手动重复工作了!Skills技术让AI自动执行你的任务,收藏这篇就够了