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

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

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

'hoc1' is up to date make ΠΏΠΎΠ½ΠΈΠΌΠ°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ это Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ

$

8.2 Π­Ρ‚Π°ΠΏ 2: ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΈ восстановлСниС послС ошибки

Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ шаг ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ ΠΎΡ‚

hoc1
ΠΊ
hoc2
, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ сводится ΠΊ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡŽ памяти (Π² памяти хранится 26 ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… с ΠΈΠΌΠ΅Π½Π°ΠΌΠΈ ΠΎΡ‚
Π°
Π΄ΠΎ
z
). Π­Ρ‚ΠΎ довольно нСслоТный ΠΈ вСсьма ΠΏΠΎΠ»Π΅Π·Π½Ρ‹ΠΉ ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΎΡ‡Π½Ρ‹ΠΉ этап. ΠœΡ‹ Ρ‚Π°ΠΊΠΆΠ΅ Π²Π²Π΅Π΄Π΅ΠΌ здСсь процСсс ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ошибок. Если Π²Ρ‹ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚Π΅
hoc1
, Ρ‚ΠΎ ΡƒΠ±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ Ρ€Π΅Π°ΠΊΡ†ΠΈΠ΅ΠΉ Π½Π° синтаксичСскиС ошибки ΡΠ²Π»ΡΡŽΡ‚ΡΡ Π²Ρ‹Π²ΠΎΠ΄ сообщСния ΠΈ ΠΏΡ€Π΅ΠΊΡ€Π°Ρ‰Π΅Π½ΠΈΠ΅ Ρ€Π°Π±ΠΎΡ‚Ρ‹. ПовСдСниС ΠΆΠ΅
hoc1
Π² случаС арифмСтичСских ошибок Ρ‚ΠΈΠΏΠ° дСлСния Π½Π° Π½ΡƒΠ»ΡŒ достойно всячСского порицания:

$ hoc1

1/0

Floating exception - core dump

$

Для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π½ΠΎΠ²Ρ‹Ρ… возмоТностСй Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ΡΡ лишь нСбольшиС измСнСния: ΠΏΡ€ΠΈΠ±Π»ΠΈΠ·ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ 35 строк тСкста. ЛСксичСский Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€

yylex
Π΄ΠΎΠ»ΠΆΠ΅Π½ Ρ€Π°ΡΠΏΠΎΠ·Π½Π°Π²Π°Ρ‚ΡŒ Π±ΡƒΠΊΠ²Ρ‹ ΠΊΠ°ΠΊ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅, Π° Π³Ρ€Π°ΠΌΠΌΠ°Ρ‚ΠΈΠΊΠ° ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ ΠΏΡ€Π°Π²ΠΈΠ»Π° Π²Ρ‹Π²ΠΎΠ΄Π° Π²ΠΈΠ΄Π°

expr: VAR

Β | VAR '=' expr

Π’Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ присваивания; Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠ½ΠΎΠ³ΠΎΠΊΡ€Π°Ρ‚Π½Ρ‹Π΅ присваивания Ρ‚ΠΈΠΏΠ°

x = y = z = 0

ΠŸΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠΈΠΉ способ хранСния Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ массив ΠΈΠ· 26 элСмСнтов; ΠΎΠ΄Π½ΠΎΠ±ΡƒΠΊΠ²Π΅Π½Π½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² качСствС индСкса массива. Однако Ссли Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Ρƒ прСдстоит ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ ΠΈ ΠΈΠΌΠ΅Π½Π° ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…, ΠΈ значСния Π² ΠΎΠ΄Π½ΠΎΠΌ стСкС, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡΠΎΠΎΠ±Ρ‰ΠΈΡ‚ΡŒ

yacc
, Ρ‡Ρ‚ΠΎ элСмСнт стСка являСтся объСдинСниСм
double
ΠΈ
int
, Π° Π½Π΅ просто элСмСнтом Ρ‚ΠΈΠΏΠ°
double
. Π­Ρ‚ΠΎ дСлаСтся с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ описания
%union
. Описания
#define
ΠΈΠ»ΠΈ
typedef
подходят для опрСдСлСния стСка ΠΈΠ· Π±Π°Π·ΠΎΠ²Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² ΠΊΠ°ΠΊ
double
, Π½ΠΎ для Ρ‚ΠΈΠΏΠΎΠ² объСдинСния трСбуСтся описаниС
%union
, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ
yacc
осущСствляСт ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒ Ρ‚ΠΈΠΏΠΎΠ² Π² выраТСниях Π²ΠΈΠ΄Π°
$$ = $2
.

НиТС ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° Ρ‡Π°ΡΡ‚ΡŒ опрСдСлСния Π³Ρ€Π°ΠΌΠΌΠ°Ρ‚ΠΈΠΊΠΈ

hoc.y
для ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹
hoc2
:

$ cat hoc.y

%{

double mem[26]; /* memory for variables 'a'..'z' */

%}

%union {Β Β Β Β  /* stack type */

Β double val; /* actual value */

Β int index;Β  /* index into mem[] */

}

%token <val> NUMBER

%token <index> VAR

%type <val> expr

%right '='

%left '+'

%left '*' '/'

%left UNARYMINUS

%%

list: /* nothing */

Β | list '\n'

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

Β | list error '\n' { yyerrok; }

Β ;

expr: NUMBER

Β | VAR { $$ = mem[$1]; }

Β | VAR '=' expr { $$ = mem[$1] = $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 ')' { $$ = $2; }

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

Β ;

%%

/* end of grammar */

...

Из описания

%union
слСдуСт, Ρ‡Ρ‚ΠΎ элСмСнты стСка содСрТат ΠΈΠ»ΠΈ число с Π΄Π²ΠΎΠΉΠ½ΠΎΠΉ Ρ‚ΠΎΡ‡Π½ΠΎΡΡ‚ΡŒΡŽ (ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ случай), ΠΈΠ»ΠΈ Ρ†Π΅Π»ΠΎΠ΅, ΡΠ²Π»ΡΡŽΡ‰Π΅Π΅ΡΡ индСксом Π² массивС
mem
. Π’ описании
%token
Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ указываСтся Ρ‚ΠΈΠΏ значСния. Π’ описании
%type
Π΅ΡΡ‚ΡŒ свСдСния ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π²Ρ‹Ρ€Π°ΠΆ являСтся элСмСнтом объСдинСния
<val>
, Ρ‚.Π΅.
double
. Π˜Π½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡ ΠΎ Ρ‚ΠΈΠΏΠ΅ позволяСт
yacc
ΠΎΠ±Ρ€Π°Ρ‰Π°Ρ‚ΡŒΡΡ ΠΊ Π½ΡƒΠΆΠ½ΠΎΠΌΡƒ элСмСнту объСдинСния. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅:
"="
прСдставляСт собой ΠΏΡ€Π°Π²ΠΎΠ°ΡΡΠΎΡ†ΠΈΠ°Ρ‚ΠΈΠ²Π½ΡƒΡŽ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ, Ρ‚ΠΎΠ³Π΄Π° ΠΊΠ°ΠΊ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ β€” лСвоассоциативныС.

ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ошибок происходит Π² нСсколько этапов. ΠŸΡ€Π΅ΠΆΠ΄Π΅ всСго производится ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Π½Π° Π½ΡƒΠ»Π΅Π²ΠΎΠΉ Π΄Π΅Π»ΠΈΡ‚Π΅Π»ΡŒ: Ссли Π΄Π΅Π»ΠΈΡ‚Π΅Π»ΡŒ Ρ€Π°Π²Π΅Π½ Π½ΡƒΠ»ΡŽ, вызываСтся ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ошибок

execerror
. Π’Ρ‚ΠΎΡ€ΠΎΠΉ этап Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‚Π΅ сигнала "ΠΏΠ΅Ρ€Π΅ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ вСщСствСнного" ("floating point exception"), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ вСщСствСнного числа. Π‘ΠΈΠ³Π½Π°Π» устанавливаСтся Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ
main
. ПослСдний шаг восстановлСния послС ошибки Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠΈ ΠΊ Π³Ρ€Π°ΠΌΠΌΠ°Ρ‚ΠΈΠΊΠ΅ ΠΏΡ€Π°Π²ΠΈΠ»Π° Π²Ρ‹Π²ΠΎΠ΄Π° для ошибки. Π’ Π³Ρ€Π°ΠΌΠΌΠ°Ρ‚ΠΈΠΊΠ΅
yacc
слово
error
Π·Π°Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€ΠΎΠ²Π°Π½ΠΎ; ΠΎΠ½ΠΎ Π΄Π°Π΅Ρ‚ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Ρƒ ΠΎΡΠΎΠ·Π½Π°Ρ‚ΡŒ ΡΠΈΠ½Ρ‚Π°ΠΊΡΠΈΡ‡Π΅ΡΠΊΡƒΡŽ ΠΎΡˆΠΈΠ±ΠΊΡƒ ΠΈ Π²ΠΎΡΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒΡΡ послС Π½Π΅Π΅. Если ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ‚ ошибка,
yacc
Π² ΠΊΠΎΠ½Ρ†Π΅ ΠΊΠΎΠ½Ρ†ΠΎΠ² ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ это ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ, распознаСт ΠΎΡˆΠΈΠ±ΠΊΡƒ ΠΊΠ°ΠΊ грамматичСски "ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΡƒΡŽ" ΠΊΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡŽ ΠΈ, Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, восстановится. ДСйствиС
yyerrok
Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² установкС ΠΏΡ€ΠΈΠ·Π½Π°ΠΊΠ° Π² Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ позволяСт Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒΡΡ Π΅ΠΌΡƒ Π½Π°Π·Π°Π΄ Π² состояниС осмыслСнного Ρ€Π°Π·Π±ΠΎΡ€Π°. ВосстановлСниС послС ошибки слоТная ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° для всСх Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ΠΎΠ². ΠœΡ‹ ΠΏΠΎΠΊΠ°Π·Π°Π»ΠΈ Π²Π°ΠΌ здСсь лишь самыС элСмСнтарныС ΠΏΡ€ΠΈΠ΅ΠΌΡ‹ ΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡ΠΈΠ»ΠΈ возмоТности
yacc
.

Π’ Π³Ρ€Π°ΠΌΠΌΠ°Ρ‚ΠΈΠΊΠ΅

hoс2
ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»ΠΈ Π½Π΅Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ измСнСния. НиТС ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° функция
main
, дополнСнная ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ΠΌ ΠΊ
setjmp
. Оно позволяСт Π·Π°ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ Ρ‚ΠΎ Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎΠ΅ состояниС, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ использовано ΠΏΡ€ΠΈ восстановлСнии послС ошибки. Π’ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ
execerror
происходит ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π΅ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΠΊ
longjmp
. (ОписаниС
setjmp
ΠΈ
longjmp
см. Π² Ρ€Π°Π·Π΄. 7.5.)