ΠΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ %prec "Π³ΠΎΠ²ΠΎΡΠΈΡ", ΡΡΠΎ ΡΠΈΠΌΠ²ΠΎΠ» ΡΠ½Π°ΡΠ½ΠΎΠ³ΠΎ ΠΌΠΈΠ½ΡΡΠ° (Ρ.Π΅. Π·Π½Π°ΠΊ "-" ΠΏΠ΅ΡΠ΅Π΄ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ) ΠΈΠΌΠ΅Π΅Ρ ΡΠΎΡ ΠΆΠ΅ ΠΏΡΠΈΠΎΡΠΈΡΠ΅Ρ, ΡΡΠΎ ΠΈ UNARYMINUS (Π½Π°ΠΈΠ²ΡΡΡΠΈΠΉ); Π΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ Π·Π°ΠΊΠ»ΡΡΠ°Π΅ΡΡΡ Π² ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ Π·Π½Π°ΠΊΠ°. ΠΡΠΈΠΎΡΠΈΡΠ΅Ρ ΠΌΠΈΠ½ΡΡΠ° ΠΌΠ΅ΠΆΠ΄Ρ Π΄Π²ΡΠΌΡ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΡΠΌΠΈ ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΡΡΡ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ.
Π£ΠΏΡΠ°ΠΆΠ½Π΅Π½ΠΈΠ΅ 8.2ΠΠΎΠ±Π°Π²ΡΡΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ % (Π²Π·ΡΡΠΈΠ΅ ΠΎΡΡΠ°ΡΠΊΠ°) ΠΈ ΡΠ½Π°ΡΠ½ΡΠΉ ΠΏΠ»ΡΡ ΠΊ hoc1. Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°ΡΠΈΡ: ΠΎΠ±ΡΠ°ΡΠΈΡΠ΅ΡΡ ΠΊ ΡΠΏΡΠ°Π²ΠΎΡΠ½ΠΎΠΌΡ ΡΡΠΊΠΎΠ²ΠΎΠ΄ΡΡΠ²Ρ ΠΏΠΎ frexp(3).
ΠΠ΅ΠΊΠΎΡΠΎΡΡΠ΅ Π·Π°ΠΌΠ΅ΡΠ°Π½ΠΈΡ ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΠΎ makeΠΠ±ΠΈΠ΄Π½ΠΎ, ΡΡΠΎ ΠΏΡΠΈΡ ΠΎΠ΄ΠΈΡΡΡ Π²Π²ΠΎΠ΄ΠΈΡΡ Π΄Π²Π΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρ Π΄Π»Ρ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ hoc1. Π₯ΠΎΡΡ, ΠΊΠΎΠ½Π΅ΡΠ½ΠΎ, Π½Π΅ΡΡΡΠ΄Π½ΠΎ ΡΠΎΡΡΠ°Π²ΠΈΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΡΠΉ ΡΠ°ΠΉΠ» Π΄Π»Ρ ΡΠ°ΠΊΠΎΠ³ΠΎ Π·Π°Π΄Π°Π½ΠΈΡ, Π½ΠΎ Π΅ΡΡΡ Π»ΡΡΡΠΈΠΉ ΡΠΏΠΎΡΠΎΠ±, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΠΎΠ·Π΄Π½Π΅Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ°ΡΠΏΡΠΎΡΡΡΠ°Π½ΠΈΡΡ Π½Π° ΡΠΎΡ ΡΠ»ΡΡΠ°ΠΉ, ΠΊΠΎΠ³Π΄Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° ΡΠΎΡΡΠΎΠΈΡ ΠΈΠ· Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ ΠΈΡΡ ΠΎΠ΄Π½ΡΡ ΡΠ°ΠΉΠ»ΠΎΠ². ΠΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° make ΡΠΈΡΠ°Π΅Ρ ΠΎΠΏΠΈΡΠ°Π½ΠΈΡ Π²Π·Π°ΠΈΠΌΠΎΠ·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠ² ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΡΠΎΠ·Π΄Π°ΡΡ Π΅Π΅ Π΄Π΅ΠΉΡΡΠ²ΡΡΡΡΡ Π²Π΅ΡΡΠΈΡ. ΠΠ½Π° ΠΏΡΠΎΠ²Π΅ΡΡΠ΅Ρ Π²ΡΠ΅ΠΌΡ ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅ΠΉ ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΈΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ°, Π²ΡΡΡΠ½ΡΠ΅Ρ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡΠ½ΡΠΉ ΠΎΠ±ΡΠ΅ΠΌ ΠΏΠ΅ΡΠ΅ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ, ΠΊΠΎΡΠΎΡΡΡ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π²ΡΠΏΠΎΠ»Π½ΠΈΡΡ Π΄Π»Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ Π½ΠΎΠ²ΠΎΠΉ Π΄Π΅ΠΉΡΡΠ²ΡΡΡΠ΅ΠΉ Π²Π΅ΡΡΠΈΠΈ, ΠΈ Π·Π°ΡΠ΅ΠΌ Π·Π°ΠΏΡΡΠΊΠ°Π΅Ρ ΠΏΡΠΎΡΠ΅ΡΡ. ΠΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° make ΡΠ°Π·Π±ΠΈΡΠ°Π΅ΡΡΡ Π² Π·Π°ΠΏΡΡΠ°Π½Π½ΡΡ ΠΌΠ½ΠΎΠ³ΠΎΡΠ°Π³ΠΎΠ²ΡΡ ΠΏΡΠΎΡΠ΅ΡΡΠ°Ρ , Π² ΡΠ°ΡΡΠ½ΠΎΡΡΠΈ Π² yacc, ΠΏΠΎΡΡΠΎΠΌΡ Π΅ΠΉ ΠΌΠΎΠΆΠ½ΠΎ Π΄Π°Π²Π°ΡΡ Π·Π°Π΄Π°Π½ΠΈΡ, Π½Π΅ ΡΡΠΎΡΠ½ΡΡ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠ΅ ΡΠ°Π³ΠΈ.
ΠΡΠΎΠ±Π΅Π½Π½ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ ΠΎΠ±ΡΠ°ΡΠ°ΡΡΡΡ ΠΊ make, ΠΊΠΎΠ³Π΄Π° ΡΠΎΠ·Π΄Π°Π²Π°Π΅ΠΌΠ°Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° Π½Π°ΡΡΠΎΠ»ΡΠΊΠΎ Π²Π΅Π»ΠΈΠΊΠ°, ΡΡΠΎ "ΡΠ°ΡΠΏΠΎΠ»Π°Π³Π°Π΅ΡΡΡ" Π² Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ ΠΈΡΡ ΠΎΠ΄Π½ΡΡ ΡΠ°ΠΉΠ»Π°Ρ . ΠΠ΄Π½Π°ΠΊΠΎ ΠΎΠ½Π° ΡΠ΄ΠΎΠ±Π½Π° ΠΈ Π΄Π»Ρ ΡΠ°ΠΊΠΈΡ ΠΌΠ°Π»ΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌ, ΠΊΠ°ΠΊ hoc1. ΠΠΈΠΆΠ΅ ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½Ρ ΠΎΠΏΠΈΡΠ°Π½ΠΈΡ ΠΊΠΎΠΌΠ°Π½Π΄ Π΄Π»Ρ make, ΡΠ°ΡΡΡΠΈΡΠ°Π½Π½ΡΠ΅ Π½Π° hoc1, ΠΊΠΎΡΠΎΡΡΠ΅ make ΠΏΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅Ρ Π½Π°ΠΉΡΠΈ Π² ΡΠ°ΠΉΠ»Π΅ Ρ ΠΈΠΌΠ΅Π½Π΅ΠΌ makefile.
$ cat makefile
hoc1: hoc.o
cc hoc.o -o hoc1
$
ΠΠ΄Π΅ΡΡ ΡΠΎΠΎΠ±ΡΠ°Π΅ΡΡΡ, ΡΡΠΎ hoc1 Π·Π°Π²ΠΈΡΠΈΡ ΠΎΡ hoc.o ΠΈ ΡΡΠΎ hoc1 ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ ΠΈΠ· hoc.o Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Ρ ΡΡ, ΠΊΠΎΡΠΎΡΠ°Ρ Π·Π°ΠΏΡΡΠΊΠ°Π΅Ρ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡ Π‘ΠΈ, ΠΏΠΎΠΌΠ΅ΡΠ°Ρ Π²ΡΡ ΠΎΠ΄Π½ΠΎΠΉ ΠΏΠΎΡΠΎΠΊ Π² ΡΠ°ΠΉΠ» hoc1. ΠΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° make ΡΠΆΠ΅ "Π·Π½Π°Π΅Ρ", ΠΊΠ°ΠΊ ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°ΡΡ Π²Ρ ΠΎΠ΄Π½ΠΎΠΉ ΡΠ°ΠΉΠ» Π΄Π»Ρ yacc hoc.y Π² Π²ΡΡ ΠΎΠ΄Π½ΠΎΠΉ ΡΠ°ΠΉΠ» hoc.o:
$ make ΠΡΠΎΠ΄Π΅Π»Π°Π΅ΠΌ ΠΏΠ΅ΡΠ²ΡΠΉ ΡΠ°Π· ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΠ΅ hoc1 Ρ ΠΏΠΎΠΌΠΎΡΡΡ make
yacc hoc.y
ΡΡ -Ρ y.tab.c
rm y.tab.c
mv y.tab.o hoc.ΠΎ
ΡΡ hoc.ΠΎ -ΠΎ hoc1
$ make ΠΠΎΠΏΡΠΎΠ±ΡΠ΅ΠΌ Π΅ΡΠ΅ ΡΠ°Π·
'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.)
...
#include <stdio.h>
#include <ctype.h>
char *progname;
int lineno = 1;
#include <signal.h>
#include <setjmp.h>
jmp_buf begin;
main(argc, argv) /* hoc2 */
char *argv[];
{
int fpecatch();
progname = argv[0];
setjmp(begin);
signal(SIGFPE, fpecatch);
yyparse();
}
execerror(s, t) /* recover from run-time error */
char *s, *t;
{
warning(s, t);
longjmp(begin, 0);
}
fpecatch() /* catch floating point exceptions */
{
execerror("floating point exception", (char*)0);
}
Π ΡΠ΅Π»ΡΡ ΠΎΡΠ»Π°Π΄ΠΊΠΈ ΠΌΡ ΡΠΎΡΠ»ΠΈ ΡΠ΄ΠΎΠ±Π½ΡΠΌ, ΡΡΠΎΠ±Ρ ΡΡΠ½ΠΊΡΠΈΡ execerror Π²ΡΠ·ΡΠ²Π°Π»Π° abort (ΡΠΌ. ΡΠΏΡΠ°Π²ΠΎΡΠ½ΠΎΠ΅ ΡΡΠΊΠΎΠ²ΠΎΠ΄ΡΡΠ²ΠΎ ΠΏΠΎ abort(3)), ΡΡΠΎ ΠΏΡΠΈΠ²Π΅Π΄Π΅Ρ ΠΊ ΡΠ°ΡΠΏΠ΅ΡΠ°ΡΠΊΠ΅ ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠ³ΠΎ ΠΏΠ°ΠΌΡΡΠΈ, ΠΊΠΎΡΠΎΡΡΡ Π·Π°ΡΠ΅ΠΌ ΡΠΌΠΎΠ³ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ adb ΠΈ sdb. ΠΠΎΠ³Π΄Π° ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ Π·Π°Π²Π΅ΡΡΠΈΡΡΡ, ΠΎΠ±ΡΠ°ΡΠ΅Π½ΠΈΠ΅ ΠΊ abort Π±ΡΠ΄Π΅Ρ Π·Π°ΠΌΠ΅Π½Π΅Π½ΠΎ Π½Π° longjmp.
Π ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ΅ hoc2 Π»Π΅ΠΊΡΠΈΡΠ΅ΡΠΊΠΈΠΉ Π°Π½Π°Π»ΠΈΠ·Π°ΡΠΎΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΈΠ½ΠΎΠΉ. Π Π½Π΅ΠΌ ΡΡΡΠ΅Π½ΠΎ ΡΠ°Π·Π»ΠΈΡΠΈΠ΅ ΡΡΡΠΎΡΠ½ΡΡ ΠΈ ΠΏΡΠΎΠΏΠΈΡΠ½ΡΡ Π±ΡΠΊΠ², Π° ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΡΠ΅ΠΏΠ΅ΡΡ yyval ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ΠΌ, Π½ΡΠΆΠ½ΠΎ Π²ΡΠ±ΡΠ°ΡΡ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΡΡΠΈΠΉ ΡΠ»Π΅ΠΌΠ΅Π½Ρ ΠΏΠ΅ΡΠ΅Π΄ Π²ΡΡ ΠΎΠ΄ΠΎΠΌ ΠΈΠ· yylex. ΠΠΈΠΆΠ΅ ΠΏΠΎΠΊΠ°Π·Π°Π½Ρ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½Π½ΡΠ΅ ΡΡΠ°Π³ΠΌΠ΅Π½ΡΡ:
yylex() /* hoc2 */
{
...
if (Ρ == '.' || isdigit(c)) { /* number */
ungetc(c, stdin);
scanf("%lf", &yylval.val);
return NUMBER;
}
if (islower(c)) {
yylval.index = Ρ - 'a'; /* ASCII only */
return VAR;
}
...
ΠΡΠ΅ ΡΠ°Π· ΠΎΡΠΌΠ΅ΡΠΈΠΌ, ΡΡΠΎ ΡΠΈΠΏ Π»Π΅ΠΊΡΠ΅ΠΌΡ (Ρ.Π΅. NUMBER) Π½Π΅ ΡΠΎΠ²ΠΏΠ°Π΄Π°Π΅Ρ Ρ Π΅Π΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ΠΌ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, 3.1416).