利用 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 <stdlib.h>
    #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<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')'    		{$$ = $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;
}

好的,我可以为您提供一个简单的整数计算器示例,使用FlexBison来实现解析计算表达式。以下是代码说明: 首先,我们需要创建一个flex文件(例如calc.l),来定义我们的语法规则词法分析器。以下是一个简单的例子: ``` %{ #include <stdio.h> #include "calc.tab.h" // 包含Bison生成的头文件 %} %% [0-9]+ { yylval = atoi(yytext); return NUMBER; } [\+\-\/\*\(\)] { return yytext[0]; } [ \t\n] { /* skip whitespace */ } %% int yywrap() { return 1; } ``` 这个文件定义了三个规则: - `NUMBER`:匹配整数,将其转换为C语言的整数类型,并将其存储在`yylval`中,以便Bison在解析时使用。 - `[\+\-\/\*\(\)]`:匹配运算符括号,并返回单个字符的ASCII码。 - `[ \t\n]`:跳过空格、制表符换行符。 接下来,我们需要创建一个Bison文件(例如calc.y),定义我们的语法分析器计算规则。以下是一个简单的例子: ``` %{ #include <stdio.h> #include <stdlib.h> %} %token NUMBER %left '+' '-' %left '*' '/' %left UMINUS %% input: /* 空 */ { printf("> "); } | input line { printf("> "); } ; line: '\n' | exp '\n' { printf("= %d\n", $1); } ; exp: NUMBER { $$ = $1; } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec UMINUS { $$ = -$2; } | '(' exp ')' { $$ = $2; } ; %% int main() { yyparse(); return 0; } void yyerror(char *s) { fprintf(stderr, "error: %s\n", s); } ``` 这个文件定义了以下规则: - `input`:一个空输入或多个`line`,用于读取计算多个表达式。 - `line`:一个单独的表达式,以换行符结尾。 - `exp`:一个数字、一个二元运算、一个一元运算或一个括号表达式。 在这里,我们使用了Bison的`%left``%prec`指令,用于定义运算符的优先级结合性。在表达式中,我们还支持一元减法表达式(`UMINUS`)。 最后,我们需要编译并链接我们的程序。在Unix/Linux系统中,可以使用以下命令: ``` $ flex calc.l $ bison -d calc.y $ gcc -o calc calc.tab.c lex.yy.c -lfl ``` 现在,我们可以运行我们的整数计算器,并输入一些表达式进行计算: ``` $ ./calc > 1+2 = 3 > 3*4+2 = 14 > (3+4)*2 = 14 > -5+3*2 = 1 > ^D ``` 这个简单的计算器可以通过扩展Bison规则Flex规则来支持更多的语法运算符。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值