编译原理--计算器Flex+Bison实现
一、原创性声明 本程序参考了老师给出的计算器的简单实例其余扩展程序由本人写成,属于原创。 ? 二、实验要求 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为底的对数 2? 2?完成情况:?完成 2?Bug: 2?备注:由于许多符号不好标识有的采用字母、有的采用不常用的字符、望见谅。 ? 四、实现方案 通过flex和bison的配合使用实现简单的计算器。 五、创新和亮点 可以计算加减乘除以及扩展功能:位运算、三角函数、阶乘、求模、求对数 六、运行结果 ? ? Calc.tab.h: #ifndef YYSTYPE #define YYSTYPE int #endif #define INTEGER 258 #define VARIABLE 259 extern YYSTYPE yylval; Calc.lex %{ /* * 一个简单计算器的Lex词法文件 */ #include <stdlib.h> 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("%fn",$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,"%sn",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; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |