利用 flex 和 bison 写一个计算器

利用 flex 和 bison 写一个计算器

实现实数范围内的加减乘除、乘方、开方,三角函数sin、cos运算
a)在命令提示符下依次执行一下两行命令

flex 文件名.lex
bison -o文件名.c 文件名.y

编译的话,可用命令提示符,不过需要自己搭建环境

gcc -o 可执行程序名称 lex.yy.c bison生成的文件名.c

当然可以用其他的方法去运行,不过需要在bison生成的.c文件中加入lex生成的文件的文件名,这样就可以在codeblocks里面或者其他c语言的编译环境下,直接运行bison生成的.c文件

lex程序

%{
    /*
     *  一个简单计算器的Lex词法文件
     */
    #include 
    #define YYSTYPE double
    void yyerror(char*);
   // #include "calc.tab.h"  
%}

%%




     /* a-z为变量 */   
[a-z]	{
            yylval = *yytext - 'a';
            return VARIABLE;
    	}
\.?[0-9]+|[0-9]+\.[0-9]*  {
            yylval = atof(yytext);
            return INTEGER;
    	}

[-+(),=/*\n]	{return *yytext;}

sin {return SIN;}
cos {return COS;}
sqrt {return SQRT;}
pow {return POW;}

[ \t]    ;
.    yyerror("无效的输入字符");

%%

int yywrap(void)
{
  return 1;
}

bison程序

%token    INTEGER VARIABLE COS SQRT POW SIN
%left    '+' '-'
%left    '*' '/'
%left   SIN
%{
    #define YYSTYPE double
//    #define  __STDC__   0 

    //#include "calc_d_tab.h" 
	#define YYSTYPE double
	#define pi 3.1415926
	#include
    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')'    		{$$ = $2;}
	|POW '(' expr ',' expr ')'      {$$ = pow($3,$5);}
	|SIN'('expr')' {$$ = sin($3*pi/180.0);}
	|COS '(' expr ')' {$$ = cos($3*pi/180.0);}
	|SQRT '(' expr ')'	{$$ = sqrt($3);}
    ;

%%

void yyerror(char* s)
{
    fprintf(stderr, "%s\n", s);
}

#include "lex.yy.c"

int main(void)
{
    printf("A simple calculator.\n");
    yyparse();
    return 0;
}

你可能感兴趣的:(学习笔记)