Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
posobie_CP.doc
Скачиваний:
18
Добавлен:
19.04.2015
Размер:
960.51 Кб
Скачать

4. 5 Блок-схема функции void main (int ac, char * av [ ])

В функции get () блок №1 в интерпретаторе должен быть if(nch==EOF)

{ lex=EOF;

.-.-.-.-.-.-.-.-

return;

}

Однако программа part1.c предназначена только лишь для того, чтобы прочитать текст программы на SPL, распознать лексемы, а идентификаторы занести в специальную таблицу идентификаторов char TNM [400]. Поэтому в данной программе в функции get ( ) блок №1 являет собой цикл while (nch!=EOF). Он позволяет прочитать весь текст программы на SPL до конца файла. Далее идет цикл while (isspace(nch)), позволяющий пропускать символы пробела, табуляции, перехода на новую строку и на новую страницу.

Если символ nch, прочитанный из файла с помощью функции get (), не является одним из перечисленных выше, то происходит его распознавание с вызовом функции number( ) или word( ).

Если nch является одним из перечисленных специальных символов, например, ‘(’, ‘)’, ‘+’ и т.д., то лексема получает соответствующее значение, считывается новый символ и происходит возврат в цикл (блок №1). В противном случае выдается сообщение о недопустимом символе и происходит выход из программы.

4. 5 Блок-схема функции void number ()

Блок №1 представляет собой цикл for ( ). В нем значение лексемы lval вначале определяется. Затем проверяется, что nch – цифра. Если это так, то происходит вычисление нового значения lval в блоке №2. Старое значение lval умножается на 10. К нему прибавляется результат вычитания из кода прочитанной цифры (nch) кода нуля. В таблице кодов ASCII код нуля в “10” системе равен 48, код “1” – 49, код “2” – 50 и т.д. Соответственно в “16”-ричной системе – (30)16, (31)16, (32)16 и т.д.

Таким образом, разница кодов позволяет получить прочитанную цифру. Предположим, из программы на SPL считывается константа 541. По первой цифре “5” будет вызвана функция number (). lval=0. nch содержит код цифры “5”, т.е. (35)16. Итак, условие – является ли содержимое nch кодом цифры, дает положительный ответ. В результате происходит переход к блоку №2. В нем вычисляем lval=10*0+(35)16 – (30)16 =5. После этого происходит возврат в циклы, считывается из файла новое значение nch. Это код (34)16 цифры “4”.

Теперь в блоке №2 lval=10*5+(34)16 – (30)16 =54.

После считывания кода цифры “1” lval=10*54+(31)16 – (30)16=541.

После того как очередной прочитанный символ окажется не цифрой, происходит выход из цикла. Лексема получает значение NUMB, и происходит выход из функции.

4. 5 Блок-схема функции void word ()

П

Блок №2 реализуется в виде цикла for. В указатель p заносится адрес tx[0]. Затем проверяется условие, что nch буква или цифра. Если это так, то реализуется блок №3. По адресу в указателе p, т.е. в tx[0], заносится символ nch. После этого значение p увеличивается на 1, то есть в р находится адрес tx [1]. Происходит возвращение в цикл. Считывается новое значение nch. Если он буква или цифра, вновь выполняется блок №2. теперь уже символ nch заносится в tx [1], после чего в р заносится адрес tx [2] и т.д. Если прочитанный символ nch – не буква и не цифра, происходит выход из цикла. В очередной элемент массива tx заносится ‘\0’ – признак конца строки символов. В tx сформирована некая последовательность букв или букв и цифр. Теперь предстоит проверить, что собой она представляет. Это может быть одно из служебных (зарезервированных) слов, перечисленных в массиве char*serv [] .

Проверка выполняется в цикле (блоки №5 и №6). В случае совпадения строки символов tx и одного из служебных слов lex получает значение соответствующего элемента из массива int cdl [ ].

Например, если в tx находится строка символов end, то она совпадает с элементом end из seev [1] и лексема lex=ENDL, т.е. lex=258 (см. enum={BEGINL=257, ENDL…};).

Если содержимое tx не совпало ни с одним служебным словом, значит, - это идентификатор переменной или функции. В этом случае lex=IDEN, т.е. 269, и его необходимо занести в таблицу идентификаторов char TNM [400]. Для этого вызывается функция add (tx). Она возвращает указатель char*. Поэтому, чтобы присвоить возвращаемый адрес переменной целого типа int lval, применяется явное преобразование типа

lval=(int) add (tx).

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]