flex与bison学习之简易计算器

第1章例子-简易计算器

flowchart LR A([第一章-flex与bison简介]) A-->B[字数统计] A-->C[英式英语转换为美式英语] A-->D[一个简单的flex词法分析器] A-->E[识别计算器的记号] A-->F[<u>简易计算器</u>] A-->G[简易计算器_C语言实现词法分析] classDef highlight fill:#ffc107,font-weight:bold; class F highlight;

字数统计
英式英语转换为美式英语
一个简单的flex词法分析器
识别计算器的记号
简易计算器
简易计算器_C语言实现词法分析

简易计算器

代码(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 = -d

FLEX_INPUT_FILE = $(FILE_NAME).l
FLEX_OUTPUT_FILE = $(FILE_NAME).c
FLEX_CMD = flex
FLEX_FLAG = -o
点击展开代码剩余部分
GCC_CMD = gcc
GCC_COMPILE_FLAG = -c
GCC_OUTPUT_FLAG = -o
GCC_LINK_FLAG = -lfl
GCC_OBJECT_FILE = $(FILE_NAME).o

TARGET_FILE = $(FILE_NAME)

all: clean bison_main flex_main gcc_main

bison_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: clean

clean:
	@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 )
// this is a comment line

image-20260223191854502

输出信息

image-20260223191916694

posted @ 2026-02-23 19:36  wilshappy  阅读(4)  评论(0)    收藏  举报