$ cat hoc.y
%{
#define YYSTYPE double /* data type of yacc stack */
%}
%token NUMBER
%left '+' /* left associative, same precedence */
%left '*' '/' /* left assoc., higher precedence */
%%
list: /* nothing */
| list '\n'
| list expr '\n' { printf("\t%.8g\n", $2); }
;
expr: NUMBER { $$ = $1; }
| expr '+' expr { $$ = $1 + $3; }
| expr '-' expr { $$ = $1 - $3; }
| expr '*' expr { $$ = $1 * $3; }
| expr '/' expr { $$ = $1 / $3; }
| '(' expr ')' { $$ = $2; }
;
%%
/* end of grammar */
...
ΠΡ Π²ΠΈΠ΄ΠΈΡΠ΅, ΠΊΠ°ΠΊ ΠΌΠ½ΠΎΠ³ΠΎ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠΈ Π·Π°ΠΊΠ»ΡΡΠ΅Π½ΠΎ Π² ΡΡΠΈΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ ΡΡΡΠΎΠΊΠ°Ρ . ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΌΡ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ Π²Π°ΠΌ Π·Π΄Π΅ΡΡ Π²ΡΠ΅ ΠΎΠ±ΡΡΡΠ½ΠΈΡΡ, Π² ΡΠ°ΡΡΠ½ΠΎΡΡΠΈ, ΠΊΠ°ΠΊ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈΠΉ Π°Π½Π°Π»ΠΈΠ·Π°ΡΠΎΡ, ΠΎΠ±ΡΠ°ΡΠΈΡΠ΅ΡΡ ΠΊ ΡΠΏΡΠ°Π²ΠΎΡΠ½ΠΎΠΌΡ ΡΡΠΊΠΎΠ²ΠΎΠ΄ΡΡΠ²Ρ ΠΏΠΎ yacc.
ΠΠ»ΡΡΠ΅ΡΠ½Π°ΡΠΈΠ²Π½ΡΠ΅ ΠΏΡΠ°Π²ΠΈΠ»Π° ΡΠ°Π·Π΄Π΅Π»Π΅Π½Ρ ΡΠΈΠΌΠ²ΠΎΠ»ΠΎΠΌ '|'. Π‘ ΠΊΠ°ΠΆΠ΄ΡΠΌ Π³ΡΠ°ΠΌΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠΌ ΠΏΡΠ°Π²ΠΈΠ»ΠΎΠΌ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΡΠ²ΡΠ·Π°Π½ΠΎ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ΅ Π΄Π΅ΠΉΡΡΠ²ΠΈΠ΅, ΠΊΠΎΡΠΎΡΠΎΠ΅ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ, ΠΊΠΎΠ³Π΄Π° ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ ΡΡΠΎΠ³ΠΎ ΠΏΡΠ°Π²ΠΈΠ»Π° ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π΅ΡΡΡ Π²ΠΎ Π²Ρ ΠΎΠ΄Π½ΠΎΠΌ ΠΏΠΎΡΠΎΠΊΠ΅. ΠΠ΅ΠΉΡΡΠ²ΠΈΠ΅ ΠΎΠΏΠΈΡΡΠ²Π°Π΅ΡΡΡ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΡΡΡΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΠΎΠ² Π‘ΠΈ, Π·Π°ΠΊΠ»ΡΡΠ΅Π½Π½ΠΎΠΉ Π² ΡΠΈΠ³ΡΡΠ½ΡΠ΅ ΡΠΊΠΎΠ±ΠΊΠΈ. ΠΠ½ΡΡΡΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ $n (Ρ.Π΅. $1, $2 ΠΈ Ρ.Π΄.) ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅, Π²ΡΡΠ°Π±Π°ΡΡΠ²Π°Π΅ΠΌΠΎΠ΅ n-ΠΌ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠΌ ΠΏΡΠ°Π²ΠΈΠ»Π°, Π° $$ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅, Π²ΡΡΠ°Π±Π°ΡΡΠ²Π°Π΅ΠΌΠΎΠ΅ Π²ΡΠ΅ΠΌΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ°ΠΌΠΈ ΠΏΡΠ°Π²ΠΈΠ»Π° Π² ΡΠ΅Π»ΠΎΠΌ. Π’Π°ΠΊ, Π² ΠΏΡΠ°Π²ΠΈΠ»Π΅
expr: NUMBER { $$ = $1; }
$1 β Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅, Π²ΡΡΠ°Π±Π°ΡΡΠ²Π°Π΅ΠΌΠΎΠ΅ ΠΏΡΠΈ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΠΈ NUMBER, ΠΈ ΠΎΠ½ΠΎ ΠΆΠ΅ ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠ΅Π·ΡΠ»ΡΡΠΈΡΡΡΡΠΈΠΌ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ΠΌ expr. Π Π΄Π°Π½Π½ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΏΡΠΈΡΠ²Π°ΠΈΠ²Π°Π½ΠΈΠ΅ $$ = $1 ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΠΎΠΏΡΡΠ΅Π½ΠΎ, ΡΠ°ΠΊ ΠΊΠ°ΠΊ $$ Π²ΡΠ΅Π³Π΄Π° ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ $1 (Π΅ΡΠ»ΠΈ Π½Π΅ ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΡΡΡ ΡΠ²Π½ΠΎ ΠΊΠ°ΠΊΠΈΠΌ Π»ΠΈΠ±ΠΎ ΠΈΠ½ΡΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ). Π ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΉ ΡΡΡΠΎΠΊΠ΅ Ρ ΠΏΡΠ°Π²ΠΈΠ»ΠΎΠΌ
expr: expr '+' expr { $$ = $1 + $3; }
ΡΠ΅Π·ΡΠ»ΡΡΠΈΡΡΡΡΠ΅Π΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ expr ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΡΠΌΠΌΠΎΠΉ Π΄Π²ΡΡ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠ², ΡΠΎΠΆΠ΅ expr. ΠΡΠΌΠ΅ΡΠΈΠΌ, ΡΡΠΎ $2 ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΠ΅Ρ '+' Ρ.Π΅. ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ ΠΏΡΠΎΠ½ΡΠΌΠ΅ΡΠΎΠ²Π°Π½.
Π‘ΡΡΠΎΠΊΠΎΠΉ Π²ΡΡΠ΅ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠ΅, Π·Π° ΠΊΠΎΡΠΎΡΡΠΌ ΡΠ»Π΅Π΄ΡΠ΅Ρ ΡΠΈΠΌΠ²ΠΎΠ» ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄Π° ΡΡΡΠΎΠΊΠΈ ('\n'), ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π΅ΡΡΡ ΠΊΠ°ΠΊ ΡΠΏΠΈΡΠΎΠΊ, ΠΈ ΠΏΠ΅ΡΠ°ΡΠ°Π΅ΡΡΡ Π΅Π³ΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅. ΠΡΠ»ΠΈ Π·Π° ΡΠ°ΠΊΠΎΠΉ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΈΠ΅ΠΉ ΡΠ»Π΅Π΄ΡΠ΅Ρ ΠΊΠΎΠ½Π΅Ρ Π²Ρ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ°, ΠΏΡΠΎΡΠ΅ΡΡ ΡΠ°Π·Π±ΠΎΡΠ° Π·Π°Π²Π΅ΡΡΠ°Π΅ΡΡΡ ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎ. Π‘ΠΏΠΈΡΠΎΠΊ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΠΏΡΡΡΠΎΠΉ ΡΡΡΠΎΠΊΠΎΠΉ; ΡΠ°ΠΊ ΡΡΠΈΡΡΠ²Π°ΡΡΡΡ ΠΏΡΡΡΡΠ΅ Π²Ρ ΠΎΠ΄Π½ΡΠ΅ ΡΡΡΠΎΠΊΠΈ.
Π€ΠΎΡΠΌΠ°Ρ Π²Ρ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ° Π΄Π»Ρ yacc β ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ»ΡΠ½ΡΠΉ. ΠΠ°Ρ ΡΠΎΡΠΌΠ°Ρ ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡΠ΅ΡΡΡ ΠΊΠ°ΠΊ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΡΠΉ.
Π ΡΡΠΎΠΉ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΏΡΠΎΡΠ΅ΡΡ ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΡ ΠΈΠ»ΠΈ ΡΠ°Π·Π±ΠΎΡΠ° Π²Ρ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ° ΠΏΡΠΈΠ²ΠΎΠ΄ΠΈΡ ΠΊ Π½Π΅ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎΠΌΡ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΡ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΡ. Π Π±ΠΎΠ»Π΅Π΅ ΡΠ»ΠΎΠΆΠ½ΡΡ ΡΠ΅ΡΠ΅Π½ΠΈΡΡ (Π²ΠΊΠ»ΡΡΠ°Ρ hoc4 ΠΈ Π΅Π³ΠΎ ΠΏΠΎΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ Π²Π΅ΡΡΠΈΠΈ) ΠΏΡΠΎΡΠ΅ΡΡ ΡΠ°Π·Π±ΠΎΡΠ° ΠΏΠΎΡΠΎΠΆΠ΄Π°Π΅Ρ ΠΊΠΎΠ΄ Π΄Π»Ρ Π΄Π°Π»ΡΠ½Π΅ΠΉΡΠ΅Π³ΠΎ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ.
ΠΠ°Π³Π»ΡΠ΄Π½ΠΎ ΠΏΡΠ΅Π΄ΡΡΠ°Π²ΠΈΡΡ ΡΠ°Π·Π±ΠΎΡ Π²Π°ΠΌ ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ ΡΠΈΡ. 8.1, Π³Π΄Π΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΎ Π΄Π΅ΡΠ΅Π²ΠΎ ΡΠ°Π·Π±ΠΎΡΠ°. ΠΡΠΎΠΌΠ΅ ΡΠΎΠ³ΠΎ, Π²Ρ Π΄ΠΎΠ»ΠΆΠ½Ρ Π·Π½Π°ΡΡ, ΠΊΠ°ΠΊ Π²ΡΡΠΈΡΠ»ΡΡΡΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΠΈ ΠΊΠ°ΠΊ ΠΎΠ½ΠΈ ΡΠ°ΡΠΏΡΠΎΡΡΡΠ°Π½ΡΡΡΡΡ ΠΎΡ Π»ΠΈΡΡΡΠ΅Π² ΠΊ ΠΊΠΎΡΠ½Ρ Π΄Π΅ΡΠ΅Π²Π°.
Π ΠΈΡ. 8.1: ΠΠ΅ΡΠ΅Π²ΠΎ ΡΠ°Π·Π±ΠΎΡΠ° Π΄Π»Ρ 2 + 3*4
Π Π΅Π°Π»ΡΠ½ΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΡ Π½Π΅ ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ ΡΠ°Π·ΠΎΠ±ΡΠ°Π½Π½ΡΡ ΠΏΡΠ°Π²ΠΈΠ» Ρ ΡΠ°Π½ΡΡΡΡ Π² ΡΡΠ΅ΠΊΠ΅ ΠΈ ΡΠ΅ΡΠ΅Π· ΡΡΠ΅ΠΊ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡΡΡ ΠΎΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΡΠ°Π²ΠΈΠ»Π° ΠΊ ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΌΡ. ΠΠ±ΡΡΠ½ΠΎ Π΄Π°Π½Π½ΡΠ΅ Π² ΡΡΠ΅ΠΊΠ΅ ΠΈΠΌΠ΅ΡΡ ΡΠ΅Π»ΡΠΉ ΡΠΈΠΏ, Π½ΠΎ ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΌΡ Π² ΡΠ²ΠΎΠ΅ΠΉ ΡΠ°Π±ΠΎΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ ΡΠΈΡΠ»Π° Ρ ΠΏΠ»Π°Π²Π°ΡΡΠ΅ΠΉ ΡΠΎΡΠΊΠΎΠΉ, Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΠ΅ΡΠ΅ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ. ΠΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅
#define YYSTYPE double
ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅Ρ Π΄Π²ΠΎΠΉΠ½ΡΡ ΡΠΎΡΠ½ΠΎΡΡΡ Π΄Π»Ρ ΡΠΈΠΏΠ° Π΄Π°Π½Π½ΡΡ ΡΡΠ΅ΠΊΠ°.
Π’Π΅ΠΏΠ΅ΡΡ ΠΏΠ΅ΡΠ΅ΠΉΠ΄Π΅ΠΌ ΠΊ ΠΎΠΏΠΈΡΠ°Π½ΠΈΡ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈΡ ΠΊΠ»Π°ΡΡΠΎΠ², ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π΅ΠΌΡΡ Π»Π΅ΠΊΡΠΈΡΠ΅ΡΠΊΠΈΠΌ Π°Π½Π°Π»ΠΈΠ·Π°ΡΠΎΡΠΎΠΌ, Π΅ΡΠ»ΠΈ ΡΠΎΠ»ΡΠΊΠΎ ΠΎΠ½ΠΈ Π½Π΅ ΡΠ²Π»ΡΡΡΡΡ Π»ΠΈΡΠ΅ΡΠ°Π»Π°ΠΌΠΈ, ΡΠΎΡΡΠΎΡΡΠΈΠΌΠΈ ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΡΠΈΠΌΠ²ΠΎΠ»Π° Π²ΠΈΠ΄Π° '+' ΠΈ '-'. ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅ %token ΡΠΏΠ΅ΡΠΈΡΠΈΡΠΈΡΡΠ΅Ρ ΠΎΠ΄Π½ΠΈ ΠΈΠ»ΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠ°ΠΊΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ². ΠΡΠΈ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°Π΄Π°ΡΡ Π»Π΅Π²ΡΡ ΠΈΠ»ΠΈ ΠΏΡΠ°Π²ΡΡ Π°ΡΡΠΎΡΠΈΠ°ΡΠΈΠ²Π½ΠΎΡΡΡ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ %left ΠΈΠ»ΠΈ %right Π²ΠΌΠ΅ΡΡΠΎ %token.
(ΠΠ΅Π²Π°Ρ Π°ΡΡΠΎΡΠΈΠ°ΡΠΈΠ²Π½ΠΎΡΡΡ ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ a-b-Ρ Π±ΡΠ΄Π΅Ρ ΡΠ°Π·Π±ΠΈΡΠ°ΡΡΡΡ ΠΊΠ°ΠΊ (Π° - b) - Ρ, Π° Π½Π΅ Π° - (b - Ρ).) ΠΡΠΈΠΎΡΠΈΡΠ΅Ρ ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΡΡΡ ΠΏΠΎΡΡΠ΄ΠΊΠΎΠΌ ΠΏΠΎΡΠ²Π»Π΅Π½ΠΈΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ: Π»Π΅ΠΊΡΠ΅ΠΌΡ ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΡ ΠΈΠΌΠ΅ΡΡ ΠΎΠ΄ΠΈΠ½ ΠΈ ΡΠΎΡ ΠΆΠ΅ ΠΏΡΠΈΠΎΡΠΈΡΠ΅Ρ, Π° Π»Π΅ΠΊΡΠ΅ΠΌΡ, ΡΠΏΠ΅ΡΠΈΡΠΈΡΠΈΡΠΎΠ²Π°Π½Π½ΡΠ΅ ΠΏΠΎΠ·Π΄Π½Π΅Π΅, β Π±ΠΎΠ»Π΅Π΅ Π²ΡΡΠΎΠΊΠΈΠΉ. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, Π² Π³ΡΠ°ΠΌΠΌΠ°ΡΠΈΠΊΠ΅ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ Π½Π΅ΠΎΠ΄Π½ΠΎΠ·Π½Π°ΡΠ½ΠΎΡΡΡ (Ρ.Π΅. Π΄Π»Ρ Π½Π΅ΠΊΠΎΡΠΎΡΡΡ Π²Ρ ΠΎΠ΄Π½ΡΡ ΠΏΠΎΡΠΎΠΊΠΎΠ² ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠΏΠΎΡΠΎΠ±ΠΎΠ² ΡΠ°Π·Π±ΠΎΡΠ°), Π½ΠΎ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½Π°Ρ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ Π² ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΡΡ ΡΠ°Π·ΡΠ΅ΡΠ°Π΅Ρ ΡΡΡ Π½Π΅ΠΎΠ΄Π½ΠΎΠ·Π½Π°ΡΠ½ΠΎΡΡΡ.
ΠΡΠΎΡΡΡ ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½Ρ ΡΠ°ΠΉΠ»Π° hoc.y ΡΠΎΡΡΠ°Π²Π»ΡΡΡ ΠΏΡΠΎΡΠ΅Π΄ΡΡΡ:
/* ΠΡΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ΠΈΠ΅ hoc.y */
#include <stdio.h>
#include <ctype.h>
char *progname; /* for error messages */
int lineno = 1;
main(argc, argv) /* hoc1 */
char *argv[];
{
progname = argv[0];
yyparse();
}
Π€ΡΠ½ΠΊΡΠΈΡ main ΠΎΠ±ΡΠ°ΡΠ°Π΅ΡΡΡ ΠΊ yyparse Π΄Π»Ρ ΡΠ°Π·Π±ΠΎΡΠ° Π²Ρ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ°. ΠΠ΅ΡΠ΅Ρ ΠΎΠ΄ Π² ΡΠΈΠΊΠ»Π΅ ΠΎΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΡ ΠΊ Π΄ΡΡΠ³ΠΎΠΌΡ ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ Π² ΡΠ°ΠΌΠΊΠ°Ρ Π³ΡΠ°ΠΌΠΌΠ°ΡΠΈΠΊΠΈ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ ΠΏΡΠ°Π²ΠΈΠ» Π²ΡΠ²ΠΎΠ΄Π° Π΄Π»Ρ ΡΠΏΠΈΡΠΊΠ°. ΠΡΠΈΠ΅ΠΌΠ»Π΅ΠΌΠΎ ΡΠ°ΠΊΠΆΠ΅ ΠΎΠ±ΡΠ°ΡΠ°ΡΡΡΡ Π² ΡΠΈΠΊΠ»Π΅ ΠΊ yyparse ΠΈΠ· ΡΡΠ½ΠΊΡΠΈΠΈ main, Π΅ΡΠ»ΠΈ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ Π΄Π»Ρ ΡΠΏΠΈΡΠΊΠ° ΠΏΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°ΡΡ ΠΏΠ΅ΡΠ°ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΠΈ Π½Π΅ΠΌΠ΅Π΄Π»Π΅Π½Π½ΡΠΉ Π²ΠΎΠ·Π²ΡΠ°Ρ.
Π€ΡΠ½ΠΊΡΠΈΡ yyparse Π² ΡΠ²ΠΎΡ ΠΎΡΠ΅ΡΠ΅Π΄Ρ ΠΌΠ½ΠΎΠ³ΠΎΠΊΡΠ°ΡΠ½ΠΎ ΠΎΠ±ΡΠ°ΡΠ°Π΅ΡΡΡ Π·Π° Π»Π΅ΠΊΡΠ΅ΠΌΠ°ΠΌΠΈ ΠΈΠ· Π²Ρ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ° ΠΊ ΡΡΠ½ΠΊΡΠΈΠΈ yylex. ΠΠ°ΡΠ° ΡΡΠ½ΠΊΡΠΈΡ yylex ΠΏΡΠΎΡΡΠ°: Π² Π΅Π΅ Π·Π°Π΄Π°ΡΠΈ Π²Ρ ΠΎΠ΄ΡΡ ΠΏΡΠΎΠΏΡΡΠΊ ΠΏΡΠΎΠ±Π΅Π»ΠΎΠ² ΠΈ ΡΠΈΠΌΠ²ΠΎΠ»ΠΎΠ² ΡΠ°Π±ΡΠ»ΡΡΠΈΠΈ, ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ ΡΠΈΡΡΠΎΠ²ΡΡ ΡΡΡΠΎΠΊ Π² ΡΠΈΡΠ»ΠΎΠ²ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΈ ΠΏΠΎΠ΄ΡΡΠ΅Ρ Π²Ρ ΠΎΠ΄Π½ΡΡ ΡΡΡΠΎΠΊ Π΄Π»Ρ Π²ΡΠ²ΠΎΠ΄Π° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΠΎΠ± ΠΎΡΠΈΠ±ΠΊΠ°Ρ . ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ Π³ΡΠ°ΠΌΠΌΠ°ΡΠΈΠΊΠ° Π΄ΠΎΠΏΡΡΠΊΠ°Π΅Ρ ΡΠΎΠ»ΡΠΊΠΎ +, -, *, /, (, ) ΠΈ \n, ΠΏΡΠΈ ΠΏΠΎΡΠ²Π»Π΅Π½ΠΈΠΈ Π»ΡΠ±ΠΎΠ³ΠΎ Π΄ΡΡΠ³ΠΎΠ³ΠΎ ΡΠΈΠΌΠ²ΠΎΠ»Π° yyparse Π²ΡΠ΄Π°Π΅Ρ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΠΎΠ± ΠΎΡΠΈΠ±ΠΊΠ΅. ΠΠΎΠ»ΡΡΠ΅Π½ΠΈΠ΅ 0 ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ Π΄Π»Ρ yyparse "ΠΊΠΎΠ½Π΅Ρ ΡΠ°ΠΉΠ»Π°".
/* ΠΡΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ΠΈΠ΅ hoc.y */
yylex() /* hoc1 */
{
int Ρ;
while ((c=getchar()) == ' ' || Ρ == '\t')
;
if (c == EOF)
return 0;
if (c == '.' || isdigit(c)) {
/* number */
ungetc(c, stdin);
scanf("%lf", &yylval);
return NUMBER;
}
if (c == '\n')
lineno++;
return Ρ;
}
ΠΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ yylval ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π»Ρ ΡΠ²ΡΠ·ΠΈ ΠΌΠ΅ΠΆΠ΄Ρ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈΠΌ ΠΈ Π»Π΅ΠΊΡΠΈΡΠ΅ΡΠΊΠΈΠΌ Π°Π½Π°Π»ΠΈΠ·Π°ΡΠΎΡΠ°ΠΌΠΈ; ΠΎΠ½Π° ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π° Π² yyparse ΠΈ ΠΈΠΌΠ΅Π΅Ρ ΡΠΎΡ ΠΆΠ΅ ΡΠΈΠΏ, ΡΡΠΎ ΡΡΠ΅ΠΊ yacc. Π€ΡΠ½ΠΊΡΠΈΡ yylex Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ΡΠΈΠΏ Π»Π΅ΠΊΡΠ΅ΠΌΡ, ΡΠ°Π²Π½ΠΎ ΠΊΠ°ΠΊ ΠΈ Π΅Π΅ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅, ΠΈ ΠΏΡΠΈΡΠ°Π²Π½ΠΈΠ²Π°Π΅Ρ yylval Π·Π½Π°ΡΠ΅Π½ΠΈΡ Π»Π΅ΠΊΡΠ΅ΠΌΡ (Π΅ΡΠ»ΠΈ ΠΎΠ½ΠΎ Π΅ΡΡΡ). ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΡΠΈΡΠ»ΠΎ Ρ ΠΏΠ»Π°Π²Π°ΡΡΠ΅ΠΉ ΡΠΎΡΠΊΠΎΠΉ ΠΈΠΌΠ΅Π΅Ρ ΡΠΈΠΏ NUMBER ΠΈ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅, ΡΠΊΠ°ΠΆΠ΅ΠΌ, 12.34. ΠΠ»Ρ Π½Π΅ΠΊΠΎΡΠΎΡΡΡ Π»Π΅ΠΊΡΠ΅ΠΌ, ΠΏΡΠ΅ΠΆΠ΄Π΅ Π²ΡΠ΅Π³ΠΎ ΡΠΎΡΡΠΎΡΡΠΈΡ ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΡΠΈΠΌΠ²ΠΎΠ»Π°, ΡΠ°ΠΊΠΈΡ , ΠΊΠ°ΠΊ '+' ΠΈΠ»ΠΈ '\n', Π² Π³ΡΠ°ΠΌΠΌΠ°ΡΠΈΠΊΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΡΠΈΠΏ. Π ΡΡΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ yylval Π½Π΅ Π½ΡΠΆΠ½ΠΎ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΡΡ.
ΠΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ %token NUMBER ΠΈΠ· Π²Ρ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π° Π΄Π»Ρ yacc ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΡΠ΅ΡΡΡ Π² ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡ #define Π² Π²ΡΡ ΠΎΠ΄Π½ΠΎΠΌ ΡΠ°ΠΉΠ»Π΅ y.tab.c, ΠΏΠΎΡΡΠΎΠΌΡ NUMBER ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΠΊΠΎΠ½ΡΡΠ°Π½ΡΡ Π² Π»ΡΠ±ΠΎΠΌ ΠΌΠ΅ΡΡΠ΅ Π‘ΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ. Yacc Π²ΡΠ±ΠΈΡΠ°Π΅Ρ ΡΠ°ΠΊΠΈΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ, ΠΊΠΎΡΠΎΡΡΠ΅ Π½Π΅ Π±ΡΠ΄ΡΡ ΡΠΌΠ΅ΡΠΈΠ²Π°ΡΡΡΡ Ρ ΡΠΈΠΌΠ²ΠΎΠ»Π°ΠΌΠΈ ASCII.
ΠΡΠΈ Π½Π°Π»ΠΈΡΠΈΠΈ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΎΠΉ ΠΎΡΠΈΠ±ΠΊΠΈ yyparse ΠΎΠ±ΡΠ°ΡΠ°Π΅ΡΡΡ ΠΊ yyerror ΡΠΎ ΡΡΡΠΎΠΊΠΎΠΉ, ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠ΅ΠΉ Π·Π°Π³Π°Π΄ΠΎΡΠ½ΠΎΠ΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅: "syntax error" ("ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠ°Ρ ΠΎΡΠΈΠ±ΠΊΠ°"). ΠΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅ΡΡΡ, ΡΡΠΎ ΡΡΠ½ΠΊΡΠΈΡ yyerror ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ: Π² Π½Π°ΡΠ΅ΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ ΡΡΡΠΎΠΊΠ° ΠΏΡΠΎΡΡΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°Π΅ΡΡΡ Π΄ΡΡΠ³ΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ β warning, ΠΊΠΎΡΠΎΡΠ°Ρ Π²ΡΠ΄Π°Π΅Ρ Π½Π΅ΠΊΠΎΡΠΎΡΡΡ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ. Π ΠΏΠΎΡΠ»Π΅Π΄ΡΡΡΠΈΡ Π²Π΅ΡΡΠΈΡΡ hoc ΡΡΠ½ΠΊΡΠΈΡ warning Π±ΡΠ΄Π΅Ρ ΠΏΡΠΈΠΌΠ΅Π½ΡΡΡΡΡ Π½Π΅ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²Π΅Π½Π½ΠΎ.
yyerror(s) /* called for yacc syntax error */
char *s;
{
warning(s, (char*)0);
}
warning(s, t) /* print warning message */
char *s, *t;
{
fprintf(stderr, "%s: %s", progname, s);
if (t)
fprintf(stderr, " %s", t);
fprintf(stderr, " near line %d\n", lineno);
}
ΠΡΠΈΠΌ Π·Π°Π²Π΅ΡΡΠ°ΡΡΡΡ ΠΏΡΠΎΡΠ΅Π΄ΡΡΡ ΡΠ°ΠΉΠ»Π° hoc.y. Π’ΡΠ°Π½ΡΠ»ΡΡΠΈΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Π΄Π»Ρ yacc ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ Π² Π΄Π²Π° ΡΡΠ°ΠΏΠ°:
$ yacc hoc.y ΠΡΡ ΠΎΠ΄Π½ΠΎΠΉ ΠΏΠΎΡΠΎΠΊ ΠΏΠΎΠΏΠ°Π΄Π°Π΅Ρ Π² y.tab.c
$ ΡΡ y.tab.c -ΠΎ hoc1 ΠΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΠ°Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° ΠΏΠΎΠΏΠ°Π΄Π°Π΅Ρ Π² hoc1
$ hoc1
2/3
0.66666667
-3-4
hoc1: syntax error near line 1
$
Π£ΠΏΡΠ°ΠΆΠ½Π΅Π½ΠΈΠ΅ 8.1ΠΡΡΠ»Π΅Π΄ΡΠΉΡΠ΅ ΡΡΡΡΠΊΡΡΡΡ ΡΠ°ΠΉΠ»Π° y.tab.c (Π΄Π»Ρ hoc1 ΡΡΠΎ ΡΠΎΡΡΠ°Π²Π»ΡΠ΅Ρ ΠΎΠΊΠΎΠ»ΠΎ 300 ΡΡΡΠΎΠΊ ΡΠ΅ΠΊΡΡΠ°).
ΠΠ½Π΅ΡΠ΅Π½ΠΈΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ β ΡΠ½Π°ΡΠ½ΡΠΉ ΠΌΠΈΠ½ΡΡΠ Π°Π½Π΅Π΅ ΠΌΡ ΡΡΠ²Π΅ΡΠΆΠ΄Π°Π»ΠΈ, ΡΡΠΎ, ΡΠ°Π±ΠΎΡΠ°Ρ Ρ yacc, Π»Π΅Π³ΠΊΠΎ ΠΌΠ΅Π½ΡΡΡ ΡΠ·ΡΠΊ. Π ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΠΏΡΠΈΠΌΠ΅ΡΠ° Π΄ΠΎΠ±Π°Π²ΠΈΠΌ ΠΊ hoc1 ΡΠ½Π°ΡΠ½ΡΠΉ ΠΌΠΈΠ½ΡΡ, ΡΡΠΎΠ±Ρ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΡ ΡΠΈΠΏΠ°
-3-4
Π²ΡΡΠΈΡΠ»ΡΠ»ΠΈΡΡ, Π° Π½Π΅ ΠΎΡΠ²Π΅ΡΠ³Π°Π»ΠΈΡΡ ΠΊΠ°ΠΊ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΎΡΠΈΠ±ΠΊΠΈ. ΠΡΠ΅Π³ΠΎ Π΄Π²Π΅ ΡΡΡΠΎΠΊΠΈ Π½ΡΠΆΠ½ΠΎ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΠΎ Π²ΠΊΠ»ΡΡΠΈΡΡ Π² hoc.y. ΠΠΎΠ±Π°Π²Π»ΡΠ΅ΡΡΡ Π½ΠΎΠ²Π°Ρ Π»Π΅ΠΊΡΠ΅ΠΌΠ° UNARYMINUS Π² ΡΡ ΡΠ°ΡΡΡ Π³ΡΠ°ΠΌΠΌΠ°ΡΠΈΠΊΠΈ, Π³Π΄Π΅ Π·Π°Π΄Π°ΡΡΡΡ ΠΏΡΠΈΠΎΡΠΈΡΠ΅ΡΡ, ΡΡΠΎΠ±Ρ ΡΠ½Π°ΡΠ½ΡΠΉ ΠΌΠΈΠ½ΡΡ ΠΈΠΌΠ΅Π» Π½Π°ΠΈΠ²ΡΡΡΠΈΠΉ ΠΏΡΠΈΠΎΡΠΈΡΠ΅Ρ:
%left '+' '-'
%left '*' '/'
%left UNARYMINUS /* Π½ΠΎΠ²Π°Ρ Π»Π΅ΠΊΡΠ΅ΠΌΠ° */
ΠΡΠ°ΠΌΠΌΠ°ΡΠΈΠΊΠ° ΡΠ²Π΅Π»ΠΈΡΠΈΠ²Π°Π΅ΡΡΡ Π½Π° ΠΎΠ΄Π½ΠΎ ΠΏΡΠ°Π²ΠΈΠ»ΠΎ Π΄Π»Ρ expr:
expr: NUMBER ($$= $1;}
| '-' expr %prec UNARYMINUS {$$=- $2} /* Π½ΠΎΠ²ΠΎΠ΅ */
ΠΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ %prec "Π³ΠΎΠ²ΠΎΡΠΈΡ", ΡΡΠΎ ΡΠΈΠΌΠ²ΠΎΠ» ΡΠ½Π°ΡΠ½ΠΎΠ³ΠΎ ΠΌΠΈΠ½ΡΡΠ° (Ρ.Π΅. Π·Π½Π°ΠΊ "-" ΠΏΠ΅ΡΠ΅Π΄ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ) ΠΈΠΌΠ΅Π΅Ρ ΡΠΎΡ ΠΆΠ΅ ΠΏΡΠΈΠΎΡΠΈΡΠ΅Ρ, ΡΡΠΎ ΠΈ UNARYMINUS (Π½Π°ΠΈΠ²ΡΡΡΠΈΠΉ); Π΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ Π·Π°ΠΊΠ»ΡΡΠ°Π΅ΡΡΡ Π² ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ Π·Π½Π°ΠΊΠ°. ΠΡΠΈΠΎΡΠΈΡΠ΅Ρ ΠΌΠΈΠ½ΡΡΠ° ΠΌΠ΅ΠΆΠ΄Ρ Π΄Π²ΡΠΌΡ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΡΠΌΠΈ ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΡΡΡ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ.