Операционная система UNIX. Руководство программиста


Более сложный пример - часть 3


double dreg [26]; INTERVAL vreg [26];

%}

%start lines

%union { int ival; double dval; INTERVAL vval; }

%token <ival> DREG VREG /* индексы в массивах dreg, vreg */

%token <dval> CONST /* константа с плавающей точкой */

%type <dval> dexp /* выражение */

%type <vval> vexp /* интервальное выражение */

/* информация о приоритетах операций */

%left '+' '-' %left '*' '/' %left UMINUS /* наивысший приоритет у унарного минуса */

%% /* начало секции правил */

lines : /* пусто */ | lines line ; line : dexp '\n' { printf ("%15.8f\n", $1); } | vexp '\n' { printf ("(%15.8f, %15.8f)\n", $1.lo, $1.hi); } | DREG '=' dexp '\n' { dreg [$1] = $3; } | VREG '=' vexp '\n' { vreg [$1] = $3; } | error '\n' { yyerrok; } ;

dexp : CONST | DREG { $$ = dreg [$1]; } | dexp '+' dexp { $$ = $1 + $3; } | dexp '-' dexp { $$ = $1 - $3; } | dexp '*' dexp { $$ = $1 * $3; } | dexp '/' dexp { $$ = $1 / $3; } | '-' dexp %prec UMINUS { $$ = -$2; } | '(' dexp ')' { $$ = $2; } ;

vexp : dexp { $$.hi = $$.lo = $1; } | '(' dexp ',' dexp ')' { $$.lo = $2; $$.hi = $4; if ($$.lo > $$.hi) { printf ("нижняя граница больше верхней\n"); YYERROR; } }

| VREG { $$ = vreg[$1]; } | vexp '+' vexp { $$.hi = $1.hi + $3.hi; $$.lo = $1.lo + $3.lo; } | dexp '+' vexp { $$.hi = $1 + $3.hi; $$.lo = $1 + $3.lo; } | vexp '-' vexp { $$.hi = $1.hi - $3.hi; $$.lo = $1.lo - $3.lo; } | dexp '-' vexp { $$.hi = $1 - $3.hi; $$.lo = $1 - $3.lo; }

| vexp '*' vexp { $$ = vmul ($1.lo, $1.hi, $3); } | dexp '*' vexp { $$ = vmul ($1, $1, $3); } | vexp '/' vexp { if (dcheck ($3)) YYERROR; $$ = vdiv ($1.lo, $1.hi, $3); } | dexp '/' vexp { if (dcheck ($3)) YYERROR; $$ = vdiv ($1, $1, $3); } | '-' vexp %prec UMINUS { $$.hi = -$2.lo; $$.lo = -$2.hi; } | '(' vexp ')' { $$ = $2; } ;

%% /* начало секции подпрограмм */

#define BSZ 50 /* размер буфера для числа с плав. точкой */

/* лексический анализ */

int yylex () { register int c;

/* пропустить пробелы */ while ((c = getchar ()) == ' ') ; if (isupper (c)) { yylval.ival = c - 'A'; return (VREG); } if (islower (c)) { yylval.ival = c - 'a'; return (DREG); }




Начало  Назад  Вперед



Книжный магазин