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

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

if sym = On then S else X

который получен из порождающего правила

Л::=а,5,... a SJX. (5.18)

В этих случаях параметр si должен содержать множество начальных символов X, а s2 -множество внешних символов А (см. табл. 5.2). Подробно эта процедура показана в программе 5.5, которая представляет собой дополненную версию программы 5.4. Для удобства читателя вся программа приведена полностью, за исключением инициации глобальных переменных и процедуры gstsym, оставшихся без изменений.

Предполагаемая до сих пор схема пытается возобновить грамматический разбор, вернуться на правильный путь, пропустив один или более символов входного текста. Но это неудачная стратегия во всех случаях, когда ошибка вызвана пропуском символа. Опыт говорит о том, что такие ошибки фактически связаны с символами, выполняющими чисто синтаксические функции и не представляющими какого-либо действия. Примером служит точка с запятой в ПЛ/0. Однако, поскольку множества внешних символов дополнены определенными служебными словами, на самом деле грамматический разбор вовремя прекращает пропуск символов, т. е. ведет.себя так, как если бы забытый символ был вставлен. Это видно из той части программы (5.19), которая анализируй

2. Множество s2 дополнительных символов возобновления появление которых определенно является ошибкой, но которые ни в коем случае не следует пропускать.

3. Номер п, который присваивается ошибке, если процедура ее обнаружит.

procedure fej .s2: sytnset; n: integer); begin if -n{sym in s\) then

beginerz-o); j1 := Л+*2; ,

while -isym in si) do getojm

Процедур-у-4517) удобно использоватьт^р^-елгое в процедуру грамматического разбора для проверки, является ли текущий символ допустимым начальным символом анализируемой конструкции. Это рекомендуется во всех случаях, когда процедура X вызывается безусловно, как в операторе

if synftti then 5, else



О TOM, насколько успешно эта программа обнаруживает синтаксические ошибки и справляется с необычными ситуациями, можно судить по программе ПЛ/0 (5.20). Ее распечатка является результатом работы программы 5.5, а в табл. 5.3 перечислены возможные сообщения об ошибках, соответствующие номерам ошибок в программе 5.5.

аблица 5.3. Сообщения об ошибках, выдаваемые транслятором с ПЛ/0

1. - вместо :==

2. Нет числа после =

3. Нет = после идентификатора . Нет идентификатора после const, var, procedure

о. Пропущена запятая или точка с запятой

6. Неверный символ после описания процедуры

7. Нет оператора

8. Неверный символ после операторной части блока

9. Нет многоточия

10. Пропущена точка с запятой между операторами

11. Неописанный идентификатор

12. Недопустимое присваивание константе или процедуре.

13. Требуется :==

14. Нет идентификатора после call

15. Вызов константы или переменной вместо процедуры

(6. Требуется then 7. Требуется точка с запятой или end 8. Требуется do 9. Неверный символ после оператора 0. Требуется сравнение

1. Выражение содержит идентификатор процедуры

,22. Отсутствует правая скобка

13. Неверный символ после множителя

4. Неверный символ в начале выражения

РО. Слишком большое число

Программа (5.20) получена в результате намеренного вве-Ления синтаксических ошибок в (5.14) - (5.16),

отавные операторы. Она вставляет пропущенные точки Запятой перед ключевыми словами. Множество, называемое statbegsys, есть множество начальных символов конструкции оператор .

if sym - beginsym then begin getsym;

statement([semicoIon, endsym]+fsys); while sym in [semicolori\+statbegsys uq

.u . (519)

nsym = semicolon then getsym eise error;

statement([semicoldn, endsym]+fsys)

end;

ifsym = endsym.then getsym else error end



const m s= 7, 71 85

Tar x,y,z,g,r;

procedure multiply; var a,b

begin a u; Ъ у; z ;~ 0 .t5

while Й > 0 do

begin

if odd buoz :- z -i- a;-tl6

a :~ 2a; h := t23

end end ; procedure divide var w;

const two ~ 2, three := 3; t7

begin r ~ x; q :~ 0; w := y; tl3 t24

while w :< /* do w :== tWOw; while vc > у

begin q (2*qi w l~ w/l); tl8

if w :< 7 then

begin / := r-w q := q-\-l t23

end ;

procedure gcd; begin/ x; g ;= У




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