Чтение онлайн

ЖАНРЫ

UNIX — универсальная среда программирования
Шрифт:

3.4.1.

hoc.h

typedef struct Symbol { /* symbol table entry */

 char *name;

 short type; /* VAR, BLTIN, UNDEF */

 union {

double val; /* if VAR */

double (*ptr); /* if BLTIN */

 } u;

 struct Symbol *next; /* to link to another */

} Symbol;

Symbol *install, *lookup;

3.4.2

hoc.y

%{

#include "hoc.h"

extern double Pow;

%}

%union {

 double val; /* actual value */

 Symbol *sym; /* symbol table pointer */

}

%token <val> NUMBER

%token <sym> VAR BLTIN UNDEF

%type <val> expr asgn

%right '='

%left '+' '-'

%left '*' '/'

%left UNARYMINUS

%right '^' /* exponentiation */

%%

list: /* nothing */

 | list '\n'

 | list asgn '\n'

 | list expr '\n' { printf("\t%.8g\n", $2); }

 | list error '\n' { yyerrok; }

 ;

asgn: VAR '=' expr { $$=$1->u.val=$3; $1->type = VAR; }

 ;

expr: NUMBER

 | VAR {

if ($1->type == UNDEF)

execerror("undefined variable", $1->name);

$$ = $1->u.val;

 }

 | asgn

 | BLTIN '(' expr ')' { $$ = (*($1->u.ptr))($3); }

 | expr '+' expr { $$ = $1 + $3; }

 | expr '+' expr { $$ = $1 - $3; }

 | expr '*' expr { $$ = $1 * $3; }

 | expr '/' expr {

if ($3 == 0.0)

execerror("division by zero", "");

$$ = $1 / $3;

 }

 | expr '^' expr { $$ = Pow($1, $3); }

 | '(' expr ')' { $$ = $2; }

 | '-' expr %prec UNARYMINUS { $$ = -$2; }

 ;

%%

/* end of grammar */

#include <stdio.h>

#include <ctype.h>

char *progname;

int lineno = 1;

#include <setjmp.h>

jmp_buf begin;

main(argc, argv) /* hoc3 */

 char *argv[];

{

 progname = argv[0];

 init;

 setjmp(begin);

 yyparse;

}

yyerror(s)

 char *s;

{

 warning(s, (char *)0);

}

execerror(s, t)

 char *s, *t;

{

 warning(s, t);

 longjmp(begin, 0);

}

warning(s, t)

 char *s, *t;

{

 fprintf (stderr, "%s: %s", progname, s);

 if (t && *t)

fprintf(stderr, " %s", t);

 fprintf(stderr, " near line %d\n", lineno);

}

3.4.3

init.c

#include "hoc.h"

#include "y.tab.h"

#include <math.h>

extern double Log, Log10, Exp, Sqrt, integer;

static struct { /* Constants */

 char *name;

 double eval;

} consts [] = {

 "PI", 3.14159265358979323846,

 "E", 2.71828182845904523536,

 "GAMMA", 0.57721566490153286060, /* Euler */

 "DEG", 57.29577951308232087680, /* deg/radian */

 "PHI", 1.61803398874989484820, /* golden ratio */

 0, 0

};

static struct { /* Built-ins */

 char *name;

 double (*func);

} builtins[] = {

 "sin", sin,

 "cos", cos,

 "atan", atan,

 "log", Log, /* checks argument */

 "log10", Log10, /* checks argument */

 "exp", Exp, /* checks argument */

 "sqrt", Sqrt, /* checks argument */

 "int", integer,

 "abs", fabs,

 0, 0

};

init /* install constants and built-ins in table */

{

 int i;

 Symbol *s;

 for (i = 0; consts[i].name; i++)

install(consts[i].name, VAR, consts[i].eval);

Поделиться с друзьями: