Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1063295
  • 博文数量: 284
  • 博客积分: 8223
  • 博客等级: 中将
  • 技术积分: 3188
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-01 13:26
文章分类

全部博文(284)

文章存档

2012年(18)

2011年(33)

2010年(83)

2009年(147)

2008年(3)

分类: C/C++

2009-12-17 19:35:30

练习了下yacc与lex的使用,写了一个计算器的练习,如下
首先编辑cal.l
 

%{
#include "y.tab.h"
#include <math.h>
extern double vbltable[26];
extern YYSTYPE yylval;
%}

%%
([0-9]+|([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) {
    yylval.dval = atof(yytext); return NUMBER;
    }

[ \t] ; /* ignore white space */

[a-z] { yylval.vblno = yytext[0] - 'a'; return NAME; }

"$" { return 0; /* end of input */ }

\n |
. return yytext[0];
%%

再编辑cal.y

%{
#include <stdio.h>
double vbltable[26];
%}

%union {
    double dval;
    int vblno;
}

%token <vblno> NAME
%token <dval> NUMBER
%left '-' '+'
%left '*' '/'
%nonassoc UMINUS

%type <dval> expression
%%
statement_list: statement '\n'
    | statement_list statement '\n'
    ;

statement: NAME '=' expression { vbltable[$1] = $3; }
    | expression { printf("= %g\n", $1); }
    ;

expression: expression '+' expression { $$ = $1 + $3; }
    | expression '-' expression { $$ = $1 - $3; }
    | expression '*' expression { $$ = $1 * $3; }
    | expression '/' expression
                { if($3 == 0.0)
                        yyerror("divide by zero");
                    else
                        $$ = $1 / $3;
                }
    | '-' expression %prec UMINUS { $$ = -$2; }
    | '(' expression ')' { $$ = $2; }
    | NUMBER
    | NAME { $$ = vbltable[$1]; }
    ;
%%

int yyerror(char *str)
{
     fprintf(stderr,"Error: %s\n",str);
    return 1;
 }

int yywrap()
{
     return 1;
}
int main()
{
    printf("calculate:\n");
    yyparse();
}


最后编译下,

lex cal.l
yacc -d cal.y
cc -o tt lex.yy.c y.tab.c

执行后,可以进行下面的计算

2/3
= 0.666667
1/2
= 0.5


阅读(879) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~