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

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

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

Π’Ρ€Π΅Ρ‚ΠΈΠΉ этап β€” созданиС лСксичСского Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π΄ΠΎΠ»ΠΆΠ΅Π½ Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ Ρ€Π°Π·Π±ΠΈΡ€Π°Π΅ΠΌΡ‹ΠΉ Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ ΠΏΠΎΡ‚ΠΎΠΊ ΠΈ Ρ€Π°Π·Π±ΠΈΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ для Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Π° Π½Π° осмыслСнныС Π΅Π΄ΠΈΠ½ΠΈΡ†Ρ‹. ΠŸΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠΌ лСксичСской Π΅Π΄ΠΈΠ½ΠΈΡ†Ρ‹ Π΄Π»ΠΈΠ½ΠΎΠΉ Π² нСсколько символов ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠ»ΡƒΠΆΠΈΡ‚ΡŒ

NUMBER
; ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ³ΠΎ символа, Ρ‚Π°ΠΊΠΈΠ΅, ΠΊΠ°ΠΊ
+
ΠΈ
*
, Ρ‚Π°ΠΊΠΆΠ΅ ΡΠ²Π»ΡΡŽΡ‚ΡΡ лСксичСскими Π΅Π΄ΠΈΠ½ΠΈΡ†Π°ΠΌΠΈ. По Ρ‚Ρ€Π°Π΄ΠΈΡ†ΠΈΠΈ лСксичСскиС Π΅Π΄ΠΈΠ½ΠΈΡ†Ρ‹ Π½Π°Π·Ρ‹Π²Π°ΡŽΡ‚ лСксСмами.

На ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ этапС разрабатываСтся ΡƒΠΏΡ€Π°Π²Π»ΡΡŽΡ‰Π°Ρ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π°, которая Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€, созданный

yacc
.

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°

yacc
ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ Π³Ρ€Π°ΠΌΠΌΠ°Ρ‚ΠΈΠΊΡƒ ΠΈ сСмантичСскиС ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹ Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Ρ€Π°Π·Π±ΠΎΡ€Π° с ΠΈΠΌΠ΅Π½Π΅ΠΌ
yyparse
ΠΈ записываСт Π΅Π΅ Π² Π²ΠΈΠ΄Π΅ Ρ„Π°ΠΉΠ»Π° с тСкстом Π½Π° Π‘ΠΈ. Если
yacc
Π½Π΅ Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ ошибок, Ρ‚ΠΎ Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€, лСксичСский Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ ΠΈ ΡƒΠΏΡ€Π°Π²Π»ΡΡŽΡ‰ΡƒΡŽ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρƒ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡ‚ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, ΡΠ²ΡΠ·Π°Ρ‚ΡŒ с Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°ΠΌΠΈ Π½Π° Π‘ΠΈ ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ.

ДСйствиС

yacc
сводится ΠΊ ΠΌΠ½ΠΎΠ³ΠΎΠΊΡ€Π°Ρ‚Π½ΠΎΠΌΡƒ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΡŽ ΠΊ лСксичСскому Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Ρƒ Π·Π° лСксСмами, Ρ€Π°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΡŽ грамматичСских (синтаксичСских) конструкций Π²ΠΎ Π²Ρ…ΠΎΠ΄Π½ΠΎΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ΅ ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΡŽ сСмантичСских ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€ ΠΏΠΎ ΠΌΠ΅Ρ€Π΅ распознавания грамматичСских ΠΏΡ€Π°Π²ΠΈΠ». Π’Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ лСксичСский Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ Π½ΡƒΠΆΠ½ΠΎ ΠΏΠΎ ΠΈΠΌΠ΅Π½ΠΈ
yylex
, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΈΠΌΠ΅Π½Π½ΠΎ эту Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΈΠ½ΠΈΡ†ΠΈΠΈΡ€ΡƒΠ΅Ρ‚ Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€
yyparse
всякий Ρ€Π°Π·, ΠΊΠΎΠ³Π΄Π° Π΅ΠΌΡƒ Π½ΡƒΠΆΠ½Π° ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ лСксСма. (ВсС ΠΈΠΌΠ΅Π½Π°, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅
yacc
, Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‚ΡΡ с
y
.)

Π§Ρ‚ΠΎΠ±Ρ‹ Π±Ρ‹Ρ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΡ‡Π½Ρ‹ΠΌΠΈ, ΡƒΠΊΠ°ΠΆΠ΅ΠΌ, Ρ‡Ρ‚ΠΎ Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ ΠΏΠΎΡ‚ΠΎΠΊ для

yacc
Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΠΌΠ΅Ρ‚ΡŒ Ρ‚Π°ΠΊΠΎΠΉ Π²ΠΈΠ΄:

%{

Β ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ Π‘ΠΈ Ρ‚ΠΈΠΏΠ° #include, описания ΠΈ Ρ‚.Β Π΄.

Β Π­Ρ‚Π° Ρ‡Π°ΡΡ‚ΡŒ Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Π°.

%}

yacc-описания: лСксСмы, грамматичСскиС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅,

информация ΠΎ ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚Π°Ρ… ΠΈ ассоциативности

%%

грамматичСскиС ΠΏΡ€Π°Π²ΠΈΠ»Π° ΠΈ дСйствия

%%

Π΅Ρ‰Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ Π‘ΠΈ (Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ):

main() {

Β ...; yyparse(); ...

}

yylex() {

Β ...

}

...

Π­Ρ‚ΠΎΡ‚ ΠΏΠΎΡ‚ΠΎΠΊ поступаСт Π½Π° Π²Ρ…ΠΎΠ΄

yacc
, Π° Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ записываСтся Π² Ρ„Π°ΠΉΠ»
y.tab.c
, ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΠΉ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ структуру:

ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ Π½Π° Π‘ΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ %{ ΠΈ %}, Ссли Π΅ΡΡ‚ΡŒ

ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ Π½Π° Π‘ΠΈ ΠΈΠ· части послС Π²Ρ‚ΠΎΡ€ΠΎΠΉ ΠΊΠΎΠΌΠ±ΠΈΠ½Π°Ρ†ΠΈΠΈ %%, Ссли Π΅ΡΡ‚ΡŒ:

main() {

Β ...; yyparse(); ...

}

yylex() {

Β ...

}

...

yyparse() {

Β Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ yylex()

}

Π’Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ Ρ‚ΠΈΠΏΠΈΡ‡Π΅Π½ для систСмы UNIX:

yacc
Π²Ρ‹Π΄Π°Π΅Ρ‚ тСкст Π½Π° Π‘ΠΈ, Π° Π½Π΅ оттранслированный Ρ„Π°ΠΉΠ» (
.o
), Ρ‡Ρ‚ΠΎ являСтся Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ Π³ΠΈΠ±ΠΊΠΈΠΌ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ΠΌ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ созданный тСкст, пСрСносим ΠΈ Π»Π΅Π³ΠΊΠΎ поддаСтся Π»ΡŽΠ±ΠΎΠΌΡƒ Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΡŽ (Ссли появится Ρ…ΠΎΡ€ΠΎΡˆΠ°Ρ идСя).

Π“Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€

yacc
сам ΠΏΠΎ сСбС прСдставляСтся ΠΌΠΎΡ‰Π½Ρ‹ΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΌ срСдством. Π•Π³ΠΎ ΠΈΠ·ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎΡ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ ΠΎΡ‚ вас, ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ, Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… усилий, Π½ΠΎ всС ваши "Π·Π°Ρ‚Ρ€Π°Ρ‚Ρ‹" ΠΌΠ½ΠΎΠ³ΠΎΠΊΡ€Π°Ρ‚Π½ΠΎ окупятся. Анализаторы, создаваСмыС
yacc
, β€” нСбольшиС, эффСктивныС ΠΈ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹Π΅ (хотя Π·Π° сСмантичСскиС прСобразования ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚Π΅ Π²Ρ‹). ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, ΠΌΠ½ΠΎΠ³ΠΈΠ΅ нСприятныС ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹, связанныС с процСссом Ρ€Π°Π·Π±ΠΎΡ€Π°, Ρ€Π΅ΡˆΠ°ΡŽΡ‚ΡΡ автоматичСски. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ языковых распознаватСлСй достаточно Π»Π΅Π³ΠΊΠΎ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ ΠΈ, Ρ‡Ρ‚ΠΎ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π΅Ρ‰Π΅ Π±ΠΎΠ»Π΅Π΅ Π²Π°ΠΆΠ½ΠΎ, ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ ΠΏΠΎ ΠΌΠ΅Ρ€Π΅ ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½ΡΡ‚Π²ΠΎΠ²Π°Π½ΠΈΡ опрСдСлСния языка.

ИспользованиС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ Π½Π° этапС 1

Π˜ΡΡ…ΠΎΠ΄Π½Ρ‹ΠΉ тСкст

hoc1
состоит ΠΈΠ· грамматичСских ΠΏΡ€Π°Π²ΠΈΠ» с описаниСм дСйствий лСксичСской ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹
yylex
ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ
main
, Ρ…Ρ€Π°Π½ΠΈΠΌΡ‹Ρ… Π² ΠΎΠ΄Π½ΠΎΠΌ Ρ„Π°ΠΉΠ»Π΅
hoc.y
. (ИмСна Ρ„Π°ΠΉΠ»ΠΎΠ², содСрТащих тСкст для
yacc
, Ρ‚Ρ€Π°Π΄ΠΈΡ†ΠΈΠΎΠ½Π½ΠΎ ΠΎΠΊΠ°Π½Ρ‡ΠΈΠ²Π°ΡŽΡ‚ΡΡ Π½Π°
.y
, Π½ΠΎ это соглашСниС Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ соглашСния ΠΎ
сс
ΠΈ .c Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ сам
yacc
.) Π“Ρ€Π°ΠΌΠΌΠ°Ρ‚ΠΈΠΊΠ° составляСт ΠΏΠ΅Ρ€Π²ΡƒΡŽ ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½Ρƒ Ρ„Π°ΠΉΠ»Π°
hoc.y
:

$ 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
-ΠΌ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠΌ ΠΏΡ€Π°Π²ΠΈΠ»Π°, Π°
$$
Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π²Ρ‹Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌΠΎΠ΅ всСми ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°ΠΌΠΈ ΠΏΡ€Π°Π²ΠΈΠ»Π° Π² Ρ†Π΅Π»ΠΎΠΌ. Π’Π°ΠΊ, Π² ΠΏΡ€Π°Π²ΠΈΠ»Π΅