编译原理

您所在的位置:网站首页 一个简单的计算器怎么画的 编译原理

编译原理

2023-12-12 14:22| 来源: 网络整理| 查看: 265

一、原创性声明

本程序参考了老师给出的计算器的简单实例其余扩展程序由本人写成,属于原创。

 

二、实验要求

1. 实现以下步骤, 掌握Flex和Bison的工作过程

a) 在DOS 命令提示符下依次执行以下两行命令

flex  calc.lex

bison  -ocalc.c  calc.y

b) 编译运行 calc.c

 

2. 测试目录SRC_BISON中的范例程序,了解其功能及实现。

 

3. 参考范例程序, 用Flex和Bison实现一个功能更为强大的计算器,包含以下运算:

a) 加、减、乘、除运算

b) 乘方、开方运算

c) 位运算  – 与、或、非...

d) 三角函数运算 – sin、cos...

e) 求阶乘

f) 求模

g) 求log以e为底的对数

h) 求log以10为底的对数

 

 

三、完成情况

l 功能1 : 基本内容

i) 加、减、乘、除运算

j) 乘方、开方运算

k) 位运算  – 与、或、非...

l) 三角函数运算 – sin、cos...

m) 求阶乘

n) 求模

o) 求log以e为底的对数

p) 求log以10为底的对数

² 

² 完成情况: 完成

² Bug:

² 备注:由于许多符号不好标识有的采用字母、有的采用不常用的字符、望见谅。

 

四、实现方案

通过flex和bison的配合使用实现简单的计算器。

五、创新和亮点

可以计算加减乘除以及扩展功能:位运算、三角函数、阶乘、求模、求对数

六、运行结果

 

 

Calc.tab.h: #ifndef YYSTYPE #define YYSTYPE int #endif #define INTEGER 258 #define VARIABLE 259 extern YYSTYPE yylval; Calc.lex %{ /* * 一个简单计算器的Lex词法文件 */ #include void yyerror(char*); /* #include "calc.tab.h" */ %} %% /* a-z为变量 */ [a-z] { yylval = *yytext - 'a'; return VARIABLE; } /* 整数 */ [0-9]+ { yylval = atoi(yytext); return INTEGER; } /* 运算符 */ [-+()=/*^[&|{SCTL~X%\n] {return *yytext;} /* 空白被忽略 */ [ \t] ; /* 其他字符都是非法的 */ . yyerror("无效的输入字符"); %% int yywrap(void) { return 1; } Calc.y %token INTEGER VARIABLE %left '+' '-' %left '*' '/' %left '^' '[' %left '&' '|' '{' %left 'S' 'C' 'T' %left 'L' %left '~' %left 'X' %left '%' %{ #define YYSTYPE double #define __STDC__ 0 #define wypi (0.017453292519943) #include "calc.tab.h" #include "math.h" void yyerror(char*); int yylex(void); double sym[26]; %} %% program: program statement '\n' | ; statement: expr {printf("%f\n", $1);} |VARIABLE '=' expr {sym[(int)$1] = $3;} ; expr: INTEGER |VARIABLE {$$ = sym[(int)$1];} |expr '+' expr {$$ = $1 + $3;} |expr '-' expr {$$ = $1 - $3;} |expr '*' expr {$$ = $1 * $3;} |expr '/' expr {$$ = $1 / $3;} |expr '^' expr {$$ = pow($1,$3);} |expr '[' expr {$$ = pow($3,1.0/$1);} |expr '&' expr {$$ = (int)($1)&(int)($3);} |expr '|' expr {$$ = (int)($1)|(int)($3);} |'{' expr {$$ =!$2;} |'S' expr {$$ = sin($2*wypi);} |'C' expr {$$ = cos($2*wypi);} |'T' expr {$$ = tan($2*wypi);} |'L' expr {$$ = log10($2);} |'~' expr {$$ = log($2);} |expr 'X' { $$ = 1; while($1>1) { $$ *=$1; $1--; } } |expr '%' expr { $$=(int)($1)%(int)($3); } |'('expr')' {$$ = $2;} ; %% void yyerror(char* s) { fprintf(stderr, "%s\n", s); } #include "lex.yy.c" int main(void) { printf("A simple calculator.\n"); printf("+加、-减、*乘、/除\n"); printf(" ^ 乘方(a^b a的b次方)、[ 开方( a[b 即b开a次方)\n"); printf("&与、|或、{非\n"); printf("S (sin)、C (cos)、T (tan):三角函数\n"); printf("L以10为底的对数、~以e为底的对数\n"); printf("X求阶乘 \n"); printf("求模%% \n"); yyparse(); return 0; }



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3