русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

ПЕРЕДАЧА ПАРАМЕТРОВ


Дата добавления: 2014-11-27; просмотров: 507; Нарушение авторских прав


Снова, все мы знаем основную идею передачи параметров, но давайте просто для надежности разберем ее заново.

Вообще, процедуре предоставляется список параметров, например:

PROCEDURE FOO(X, Y, Z)

В объявлении процедуры параметры называются формальными параметрами и могут упоминаться в теле процедуры по своим именам. Имена, используемые для формальных параметров в действительности произвольны. Учитывается только позиция. В примере выше имя 'X' просто означает "первый параметр" везде, где он используется.

Когда процедура вызывается, "фактические параметры" переданные ей, связаны с формальными параметрами на взаимно-однозначном принципе.

БНФ для синтаксиса выглядит приблизительно так:

<procedure> ::= PROCEDURE <ident> '(' <param-list> ')' <begin-block>

<param_list> ::= <parameter> ( ',' <parameter> )* | null

Аналогично, вызов процедуры выглядит так:

<proc call> ::= <ident> '(' <param-list> ')'

Обратите внимание, что здесь уже есть неявное решение, встроенное в синтаксис. Некоторые языки, такие как Pascal и Ada разрешают списку параметров быть необязательным. Если нет никаких параметров, вы просто полностью отбрасываете скобки. Другие языки, типа C и Modula-2, требуют скобок даже если список пустой. Ясно, что пример, который мы только что привели, соответствует первой точке зрения. Но, сказать правду, я предпочитаю последний. Для одних процедур решение кажется должно быть в пользу "без списочного" подхода. Оператор

Initialize; ,

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

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



В любом случае, Никлаус Вирт разработал и Pascal и Modula-2. Я оправдаю его и полагаю что он имел веские причины для изменения правил во втором случае!

Само собой разумеется, легко принять любую точку зрения на то, как разрабатывать язык, так что это строго вопрос персонального предпочтения. Делайте это таким способом, какой вам больше нравится.

Перед тем как пойти дальше, давайте изменим транслятор для поддержки списка параметров (возможно пустого). Пока мы не будем генерировать никакого дополнительного кода... просто анализировать синтаксис. Код для обработки объявления имеет ту же самую форму, которую мы видели раньше когда работали со списками переменных:

{--------------------------------------------------------------}

{ Process the Formal Parameter List of a Procedure }

procedure FormalList;
begin
Match('(');
if Look <> ')' then begin
FormalParam;
while Look = ',' do begin
Match(',');
FormalParam;
end;
end;
Match(')');
end;

{--------------------------------------------------------------}

В процедуру DoProc необходимо добавить строчку для вызова FormalList:

{--------------------------------------------------------------}

{ Parse and Translate a Procedure Declaration }

procedure DoProc;
var N: char;
begin
Match('p');
N := GetName;
FormalList;
Fin;
if InTable(N) then Duplicate(N);
ST[N] := 'p';
PostLabel(N);
BeginBlock;
Return;
end;

{--------------------------------------------------------------}

Сейчас код для FormalParam всего лишь пустышка, который просто пропускает имена переменных:

{--------------------------------------------------------------}

{ Process a Formal Parameter }

procedure FormalParam;
var Name: char;
begin
Name := GetName;
end;

{--------------------------------------------------------------}

Для фактического вызова процедуры должен быть аналогичный код для обработки списка фактических параметров:

{--------------------------------------------------------------}

{ Process an Actual Parameter }

procedure Param;
var Name: char;
begin
Name := GetName;
end;

{--------------------------------------------------------------}
{ Process the Parameter List for a Procedure Call }

procedure ParamList;
begin
Match('(');
if Look <> ')' then begin
Param;
while Look = ',' do begin
Match(',');
Param;
end;
end;
Match(')');
end;

{--------------------------------------------------------------}
{ Process a Procedure Call }

procedure CallProc(Name: char);
begin
ParamList;
Call(Name);
end;

{--------------------------------------------------------------}

Обратите внимание, что CallProc больше не является просто простой подпрограммой генерации кода. Она имеет некоторую структуру. Для обработки я переименовал подпрограмму генерации кода в просто Call и вызвал ее из CallProc.

Итак, если вы добавите весь этот код в ваш транслятор и протестируете его, вы обнаружите, что действительно можете правильно анализировать синтаксис. Обращаю ваше внимание на то, что здесь нет никакой проверки того, что количество (и, позднее, тип) формальных и фактических параметров совпадает. В промышленном компиляторе, мы конечно должны делать это. Сейчас мы игнорируем эту проблему той причине, что структура нашей таблицы идентификаторов пока не дает нам места для сохранения необходимой информации. Позднее мы подготовим место для этих данных и тогда сможем работать с этой проблемой.



<== предыдущая лекция | следующая лекция ==>
ВЫЗОВ ПРОЦЕДУРЫ | СЕМАНТИКА ПАРАМЕТРОВ


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 0.226 сек.