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

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

输出信息

进阶计算器
增加对小括号以及注释的支持
代码(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

测试指令
./001_5_simple_calculator_plus
#输入以下信息,按Ctrl+D结束
1 + 2 * ( 3 + 4 )
9 / ( 10 - 7 )
// this is a comment line

输出信息


浙公网安备 33010602011771号