Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«UNIX β€” ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½Π°Ρ срСда программирования». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 108

Автор ΠšΠ΅Ρ€Π½ΠΈΠ³Π°Π½ Π‘Ρ€Π°ΠΉΠ°Π½ Уилсон

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 */

...

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π² Π³Ρ€Π°ΠΌΠΌΠ°Ρ‚ΠΈΠΊΠ΅ присутствуСт

asgn
для присваивания, ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎ
expr
для выраТСния. Входная строка, состоящая Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΈΠ·

VAR = expr

являСтся присваиваниСм, ΠΈ, ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, Π½ΠΈ ΠΎΠ΄Π½ΠΎ ΠΈΠ· Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Π½Π΅ пСчатаСтся. Π—Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅, кстати, ΠΊΠ°ΠΊ ΠΌΡ‹ Π»Π΅Π³ΠΊΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΠ»ΠΈ ΠΊ Π³Ρ€Π°ΠΌΠΌΠ°Ρ‚ΠΈΠΊΠ΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ возвСдСния Π² ΡΡ‚Π΅ΠΏΠ΅Π½ΡŒ, ΡΠ²Π»ΡΡŽΡ‰ΡƒΡŽΡΡ правоассоциативной.

Для стСка

yacc
ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π΄Ρ€ΡƒΠ³ΠΎΠ΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅
%union
: вмСсто прСдставлСния ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΊΠ°ΠΊ индСкса Π² массивС ΠΈΠ· 26 элСмСнтов Π²Π²Π΅Π΄Π΅Π½ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Ρ‚ΠΈΠΏΠ°
Symbol
. Π€Π°ΠΉΠ» ΠΌΠ°ΠΊΡ€ΠΎΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΉ
hoc.h
содСрТит ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ этого Ρ‚ΠΈΠΏΠ°.

ЛСксичСский Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ распознаСт ΠΈΠΌΠ΅Π½Π° ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…, Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ ΠΈΡ… Π² Ρ‚Π°Π±Π»ΠΈΡ†Π΅ ΠΈΠΌΠ΅Π½ ΠΈ опрСдСляСт, относятся Π»ΠΈ ΠΎΠ½ΠΈ ΠΊ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌ (

VAR
) ΠΈΠ»ΠΈ ΠΊ встроСнным функциям (
BLTIN
). Ѐункция
yylex
Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ². Π—Π°ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Π΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΈ ΠΏΡ€Π΅Π΄ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ Ρ‚ΠΈΠΏΠ°
PI
относятся ΠΊ
VAR
.

Одно ΠΈΠ· свойств ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ состоит Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π΅ΠΉ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ присвоСно Π»ΠΈΠ±ΠΎ Π½Π΅ присвоСно Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, поэтому ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΠΊ Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΉ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π΄ΠΈΠ°Π³Π½ΠΎΡΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΎΠΉ

yyparse
ΠΊΠ°ΠΊ ошибка. Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ (ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π° ΠΎΠ½Π° ΠΈΠ»ΠΈ Π½Π΅Ρ‚) Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ прСдусмотрСна Π² Π³Ρ€Π°ΠΌΠΌΠ°Ρ‚ΠΈΠΊΠ΅, Π° Π½Π΅ Π² лСксичСском Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Π΅. Когда
VAR
распознаСтся Π½Π° лСксичСском ΡƒΡ€ΠΎΠ²Π½Π΅, контСкст ΠΏΠΎΠΊΠ° Π΅Ρ‰Π΅ Π½Π΅ извСстСн, Π½ΠΎ Π½Π°ΠΌ Π½Π΅ Π½ΡƒΠΆΠ½Ρ‹ сообщСния ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ
x
Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½, хотя контСкст ΠΈ Π²ΠΏΠΎΠ»Π½Π΅ допустимый, ΠΊΠ°ΠΊ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€,
x
Π² присваивании Ρ‚ΠΈΠΏΠ°
x = 1
.

НиТС приводится измСнСнная Ρ‡Π°ΡΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

yylex
:

yylex() /* hoc3 */

{

Β ...

Β if (isalpha(c)) {

Β  Symbol *s;

Β  char sbuf[100], *p = sbuf;

Β  do {

Β Β  *p++ = c;

Β  } while ((c=getchar()) != EOF && isalnum(c));

Β  ungetc(c, stdin);

Β  *p = '\0';

Β  if ((s=lookup(sbuf)) == 0)

Β Β  s = install(sbuf, UNDEF, 0.0);

Β  yylval.sym = s;

Β  return s->type == UNDEF ? VAR : s->type;

Β }

Β ...

Π’ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

main
Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π° Π΅Ρ‰Π΅ ΠΎΠ΄Π½Π° строка, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ вызываСтся ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° ΠΈΠ½ΠΈΡ†ΠΈΠ°Ρ†ΠΈΠΈ
init
для занСсСния Π² Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ ΠΈΠΌΠ΅Π½ встроСнных ΠΈ ΠΏΡ€Π΅Π΄ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Ρ… ΠΈΠΌΠ΅Π½ Ρ‚ΠΈΠΏΠ°
PI
:

main(argc, argv) /* hoc3 */

Β char *argv[];

{

Β int fpecatch();

Β progname = argv[0];

Β init();

Β setjmp(begin);

Β signal(SIGFPE, fpecatch);

Β yyparse();

}

Π’Π΅ΠΏΠ΅Ρ€ΡŒ остался Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ„Π°ΠΉΠ»

math.с
. Для Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… стандартных матСматичСских Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ трСбуСтся ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ошибок для диагностики ΠΈ восстановлСния, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, стандартная функция ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ 0, Ссли Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ ΠΎΡ‚Ρ€ΠΈΡ†Π°Ρ‚Π΅Π»Π΅Π½. Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈΠ· Ρ„Π°ΠΉΠ»Π°
math.с
ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒ ошибок, описанный Π² Ρ€Π°Π·Π΄. 2 справочного руководства ΠΏΠΎ UNIX (см. Π³Π». 7). Π­Ρ‚ΠΎ Π±ΠΎΠ»Π΅Π΅ Π½Π°Π΄Π΅ΠΆΠ½Ρ‹ΠΉ ΠΈ пСрСносимый Π²Π°Ρ€ΠΈΠ°Π½Ρ‚, Ρ‡Π΅ΠΌ Π²Π²Π΅Π΄Π΅Π½ΠΈΠ΅ своих ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΎΠΊ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ, вСроятно, ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹Π΅ ограничСния Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ ΠΏΠΎΠ»Π½Π΅Π΅ ΡƒΡ‡ΠΈΡ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ Π² "ΠΎΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠΉ" ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅. Π€Π°ΠΉΠ» ΠΌΠ°ΠΊΡ€ΠΎΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΉ
<math.h>
содСрТит описания Ρ‚ΠΈΠΏΠΎΠ² для стандартных матСматичСских Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, Π° Ρ„Π°ΠΉΠ»
<errno.h>
β€” опрСдСлСния Ρ„Π°Ρ‚Π°Π»ΡŒΠ½Ρ‹Ρ… ошибок:

$ cat math.с

#include <math.h>

#include <errno.h>

extern int errno;

double errcheck();

double Log(x)

Β double x;

{

Β return errcheck(log(x), "log");

}

double Log10(x)

Β double x;

{

Β return errcheck(log10(x), "log10");