编译原理——实验 1.2 在 Windows平台下使用 Flex和 Bison



一、实验目的
1. 学习使用语法分析程序自动构造工具 Bison 
3
 
2. 熟悉YACC源程序语法
3. 掌握语法分析程序的自动构造方法
二、实验平台
Windows + 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)  阶乘运算 !  

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%\n]	{return *yytext;}

    /* 空白被忽略 */
[ \t]    ;

    /* 其他字符都是非法的 */
.    yyerror("无效的输入字符");

%%

int yywrap(void)
{
  return 1;
}


calc.y文件如下:

%token    INTEGER VARIABLE
%left    '+' '-'
%left    '*' '/'
%left    '^' '['
%left    '!' '&'
%left    '|' '~'
%left    'S' 'C''T'
%left    'L' '%'
%{
    #define YYSTYPE double
    #define w (0.017453292519943)
    #include <math.h>
    #define  __STDC__   0
    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 '!'         {int i,s=1;
                       for(i=1;i<=$1;i++)
                          s=s*i;
                       $$=s;
                       }
    |expr '&' expr    { $$ = (int)($1)&(int)($3);}
    |expr '|' expr    { $$ = (int)($1)|(int)($3);}
    |'~'expr          { $$ = !($2);}
    |'S''('expr')'    { $$=sin($2*(w));}
    |'C''('expr')'    { $$=cos($2*(w));}
    |'T''('expr')'    { $$ = tan($2*(w));}
    |'L''('expr')'    { $$ = log($3);}
    |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("与(&),或(|),非(~)\n");
    printf("S (sin)、C (cos)、T (tan):三角函数\n");
    printf("求对数(L),求模(%)"\n");
    printf("START:\n");
    yyparse();
    return 0;
}

心得体会:



经过这次的实验,我学到了很多新的知识和好的学习方法。说实话,刚开始并不知道这门课程的实验到底要怎么做,不知道从何做起。但是经过调试老师给的事例,不断的失败不断的重复实验,不会的问同学,看书,百度,总之就是不断重复。终于,我做出来了,这离不开同学的耐心讲解和一直坚持的自己。或许,有些事开始认为不可能,只有在自己坚持做了,才会取得成果!下次继续努力吧!




  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值