Chinaunix首页 | 论坛 | 博客
  • 博客访问: 303847
  • 博文数量: 60
  • 博客积分: 2579
  • 博客等级: 大尉
  • 技术积分: 570
  • 用 户 组: 普通用户
  • 注册时间: 2006-12-17 14:54
文章分类

全部博文(60)

文章存档

2011年(1)

2010年(1)

2009年(35)

2008年(23)

分类: C/C++

2008-06-05 08:41:24

calc.y文件
 
 

%{
#include "stdio.h"
#define NSYMS 20    /* maximum number of symbols */

struct symtab {
    char *name;
    double (*funcptr)();
    double value;
} symtab[NSYMS];

struct symtab *symlook();
#include <string.h>
#include <math.h>
%}

%union {
    double dval;
    struct symtab *symp;
}
%token <symp> NAME
%token <dval> NUMBER
%left '-' '+'
%left '*' '/'
%nonassoc UMINUS

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

statement:    NAME '=' expression    { $1->value = $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)
                        printf("divide by zero\n");
                    else
                        $$ = $1 / $3;
                }
    |    '-' expression %prec UMINUS    { $$ = -$2; }
    |    '(' expression ')'    { $$ = $2; }
    |    NUMBER
    |    NAME            { $$ = $1->value; }
    |    NAME '(' expression ')'    {
            if($1->funcptr)
                $$ = ($1->funcptr)($3);
            else {
                printf("%s not a function\n", $1->name);
                $$ = 0.0;
            }
        }
    ;
%%
/* look up a symbol table entry, add if not present */
struct symtab *symlook(char* s)
{
    char *p;
    struct symtab *sp;
    
    for(sp = symtab; sp < &symtab[NSYMS]; sp++) {
        /* is it already here? */
        if(sp->name && !strcmp(sp->name, s))
            return sp;
        
        /* is it free */
        if(!sp->name) {
            sp->name = strdup(s);
            return sp;
        }
        /* otherwise continue to next */
    }
    printf("Too many symbols\n");
    exit(1);    /* cannot continue */
} /* symlook */

addfunc(name, func)
char *name;
double (*func)();
{
    struct symtab *sp = symlook(name);
    sp->funcptr = func;
}

main()
{
    extern double sqrt(), exp(), log();

    addfunc("sqrt", sqrt);
    addfunc("exp", exp);
    addfunc("log", log);
    yyparse();
}
 yyerror(char *s)
       {
               fprintf(stderr,"%s\n",s);
       }

int yywrap()
       {
               return(1);
       }

 

calc.l

 

%{
#include "stdio.h"
#include "y.tab.h"
struct symtab {
    char *name;
    double (*funcptr)();
    double value;
};
struct symtab *symlook();
#include <math.h>
%}

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

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

[A-Za-z][A-Za-z0-9]*    {    /* return symbol pointer */
        struct symtab *sp = symlook(yytext);

        yylval.symp = sp;
        return NAME;
    }

"$"    { return 0; }

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

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