Главная  Терминология Хоора 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 [ 114 ] 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133

таг а,6: pointer; h: hpoinfer;

begin if sym in [A.. Z, empty] then begin (смл/вол) new(a); if j);/ in[A..H]then begin [нетерминальный] find(sym,h);

a.terminal:~ false; aMsym :~ h end else

begin [терминальный]

a\.terminal := true; a\.tsym := sym end ;

p := a; q := a; getsym end else

if sym = [tben

begin term(p,a,b); b\.suc := p;

new{b); b\.terminal := true; b\.tsym :== empty;

--et-o?- *Т1Г-= --

if sym = ] then getsym else error end else error end [factor] ;

beffnfactor(p,a); q := a;

whUe sym in [A.. Z,[, ewpV] do

begin./i)rrfor(flt yMC, b); b\.alt := nil; а;= 6

end;

r := fl end {terwi} ;

procedure expression (vatp,q: pointer);

var a,b,c: pointer; begJM term(p,a,c): c\.suc := nil;

while sym = , do

Ъ(ф1 getsym;

term(a\.alt, b, c): c\.suc := nil; ;= fr

end ;

q := f end [expression] ;

рюседтеparse (goal: hpointer; yat match: boolean);

var s: pointer; begin jT := goal[.entry; repeat

If ,$./£гтша/then

begin if .sf.jm sym thai

begin match true; getsym end

tlse match := (s\.tsyni = empty)



еЫparsers].тут, match);. Щ Н match tbeh s := s].sue elses := s].alt

until S -=401

0 [parse] ;

jgin {порождающие правила} getsym; new{sentinel); list:- sentinel; TiMlesym Ф йо

kbeginfind{sym,h); getsym; if sym = then getsym else error; , expression {h\.entry,p); p\.edt := nil; I if sym . fbea error; щ':- writeln; readln; getsym end ;

h := list; ok := true; [проверка, все ли символы определены whiles Ф sentinel йо begin if Л^.еи/г^ = nil then

begin wriielnQ UNDEFINED symbol h].sym); ok := false

end ;

h := h\.sup


if-lofc then goto 99; [цель]

getsyjn; find{symfi); readln; writeln; [предложения]

while -neof (input) do

begin writeC ); getsym; parse(h,ok); H if ofc Л (symJ) then writeln ( correct) else writeln ( incorrect);

readln end ; : end .

Программа 5,3. Транслятор для языка j(5.13).



S.7. ЯЗЫК ПРОГРАММИРОВАНИЯ ПЛ/0

Оставшиеся разделы этой главы посвящены разработке транслятора для языка, который мы назовем ПЛ/0. При создании этого языка учитывались два условия: во-первых, транслятор не должен оказаться слишком громоздким ДЛЯ этой книги, во-вторых, желательно было продемонстрировать большинство основных принципов трансляции языков прО' граммировании высокого уровня. Несомненно, можно было выбрать как более простой, так и более сложный язык; 1 является одним из возможных компромиссов между языкам достаточно простыми для ясности изложения и достато-ш сложными, чтобы ими стоило заниматься. Значительно боЛ

похожая разработка, состоящая из трех этапов, будет сматриваться в разд. 5.8-5.11. , Р^с

Как видно из разработки программы 5.3, програм управляемые синтаксическими таблицами, или, вернее уп ляемые структурой данных, обеспечивают свободу и гибко' отсутствующие в специальных программах грамматически' разбора. Хотя такая дополнительная гибкость в принципе нужна, она оказывается весьма существенной в транслятоп для так называемых расширяемых языков. Расширяемы^ языки можно дополнять новыми синтаксическими конструк циями более или менее по усмотрению программиста. Так ж- как входной файл программы 5.3, входной файл для транс лятора с расширяемого языка содержит раздел, определяющий расширения языка, используемые в последующей про-л'рдмме. Более сложные, схемы позволяют даже изменять язык в процессе трансляции, чередуя части транслируемой программы с разделами новых определений языка.

Однако, хотя эти идеи могут показаться весьма привлекательными, попытки реализовать подобные трансляторы оказались довольно неудачными. Дело в том, что синтаксический анализ - лишь часть всей задачи трансляции и на самом деле даже не самая существенная часть. Ее легче всего формализовать и, следовательно, представить с помощью систематизированной табличной структуры. Гораздо труднее формализовать смысл языка, т. е. выход, или результат трансляции. До сих пор эта задача не была сколько-нибудь удовлетворительно решена, и этим объясняется то, почему разработчики трансляторов относятся к расширяемым языкам с гораздо большим энтузиазмом до их реализации, чем после. Остальную часть этой главы мы посвятим разработке скромного транслятора для конкретного, небольшого языка программирования.




1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 [ 114 ] 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133