Данный файл является частью Руководства по TADS для авторов игр.
Copyright © 1987, 1996 Майкл Дж. Робертс (Michael J. Roberts). Все права защищены.

Руководство было преобразовано в формат HTML Н. К. Гайем (N. K. Guy), компания tela design.

Перевод руководства на русский язык - Валентин Коптельцев


Глава четвертая


Раздел 4.4. Резюме и краткий справочник

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

Примечание переводчика: поскольку данный раздел фактически является "выжимкой" предыдущего, по ходу текста я не стал останавливаться на особенностях работы RTADS по сравнению с "родным" TADS, ограничившись только указанием на те "точки входа", которые определены в RTADS. В конце раздела имеется диаграмма алгоритма обработки и сводная таблица "точек входа", где эти особенности вкратце перечислены.

Считывание введенной игроком команды

Первое, что СА делает вначале каждого хода - это считывание введенной команды.

  commandPrompt(0);
  // СА считывает строку, введенную с клавиатуры
  commandAfterRead(0);

Если функция commandPrompt() не определена, СА просто выводит приглашение на ввод по умолчанию (пустая строка и знак больше - ">"). Если не определена функция commandAfterRead(), СА вместо нее ничего не вызывает.

В RTADS определены обе эти функции.

Функция preparse

После считывания введенной строки СА вызывает функцию preparse(), если таковая определена.

  preparse(введенная_строка);

В RTADS определена данная функция.

Предварительный разбор команды

После этого СА разбивает команду на отдельные слова, затем вычленяет отдельные предложения (если они отделены друг от друга разделителями - специальным словом "затем", точкой, точкой с запятой и т. п.). После этого СА обрабатывает каждое из предложений (команд) отдельно.

Первым шагом обработки будет проверка того, обращена ли команда к актеру (персонажу в игре), который должен ее выполнить. Если команда начинается со словосочетания, за которым следует запятая, СА считает, что это словосочетание относится к актеру.

После считывания "актерского" словосочетания СА вычленяет остальные части предложения: глагол и относящийся к нему предлог; "прямой" объект; предлог-связку "косвенного" объекта; "косвенный" объект. За исключением глагола, всех этих частей может и не быть в команде.

В ходе фазы предварительного разбора СА может вызывать функцию parseNounPhrase(), если таковая определена в игровой программе, позволяя игре использовать собственный алгоритм разбора словосочетаний; в RTADS эта функция определена.

  parseNounPhrase(wordlist, typelist, currentIndex,
                  complainOnNoMatch, isActorCheck);

Если СА не может подобрать подходящий глагол, или если структура команды ему непонятна (не подходит ни под один из шаблонов), он вызывает определенную в игре функцию parseUnknownVerb(), если таковая имеется.

  parseUnknownVerb(actor, wordlist, typelist, errnum);

Окончательный разбор (подбор объектов)

После того, как СА закончит предварительный разбор команды, он начнет подбор объектов для нее. Если игрок ввел "пакетом" несколько команд, СА переходит к обработке каждой следующей команды только после того, как закончит подбор объектов и выполнение предыдущей.

Перед тем, как начать подбор объектов, СА вызывает определенную в игре функцию preparseCmd() (в RTADS она имеется), передавая ей в качестве аргумента список строковых значений, соответствующих отдельным лексемам, составляющим команду.

  preparseCmd(wordlist);

Далее СА окончательно подбирает глагольный объект для команды. Определившись с глаголом, СА вызывает метод roomCheck текущего главного персонажа.

  parserGetMe().roomCheck(verb);

После этого СА выполняет подбор объектов и устранение неопределенности для всех словосочетаний команды. (Обратите внимание, что разбивка на словосочетания была выполнена ранее, на стадии предварительного разбора; на данной стадии СА подбирает для словосочетаний объекты в игровой программе, которым они соответствуют). В процессе устранения неопределенности СА обращается к методам validDoList, validIoList, validDo, validIo и методам-верификаторам (verIoГлагол для "косвенных" и verDoГлагол для "прямых" объектов). Если в команде использовано специальное слово "все", СА вызывает методы doDefault или ioDefault глагольного объекта команды, чтобы получить список всех доступных объектов.

Кроме того, СА также вызовет методы disambigDobj и/или disambigIobj (по ситуации) для глагольного объекта.

  глагол.disambigDobj(actor, prep, iobj, verprop, wordlist, objlist, flaglist,
                    numberWanted, isAmbiguous, silent);

  глагол.disambigIobj(actor, prep, dobj, verprop, wordlist, objlist, flaglist,
                    numberWanted, isAmbiguous, silent);

После этого СА определяет шаблон команды (и в том числе набор методов-верификаторов и действий глагольного объекта).

Если для глагола определены только такие шаблоны команд, которые требуют больше объектов, чем указал игрок, СА пытается самостоятельно подобрать недостающие объекты. (Например, глагол "взять" требует "прямого" объекта; если игрок просто наберет "взять", не указав никаких объектов, СА будет пытаться подобрать такой объект). В первую очередь СА задействует механизм подбора объекта по умолчанию путем вызова методов doDefault или ioDefault глагольного объекта, с последующей проверкой методами-верификаторами для данного шаблона команды. Если в результате этой проверки в списке останется количество объектов, отличное от 1, СА запросит недостающий объект у игрока.

Далее, если в команде игрока перечислено более одного объекта или используется специальное слово "все", СА пытается вызвать для глагольного объекта метод rejectMultiDobj, если таковой определен.

  глагол.rejectMultiDobj(preposition);

Начало выполнения команды

Далее СА вызывает функцию preCommand, если таковая определена в игровой программе:

  preCommand(actor, verb, dobj_list, prep, iobj)

Здесь возможны три варианта: либо эта функция использует для прерывания текущей команды инструкцию abort (сразу переходя к выполнению функции endCommand, демоны и запалы выполняться не будут), или инструкцию exit (все, как в предыдущем случае, но демоны с запалами выполняться будут), либо она не использует ни одну из этих инструкций - в этом случае после того, как она завершится, обработка команды продолжится обычным образом.

Цикл по "прямым" объектам

На данной стадии СА выполняет серию вызовов методов для "прямых" объектов в команде; если таковых в команде несколько, СА вызывает весь нижеописанный набор методов последовательно для каждого из объектов.

Если текущий "прямой" объект - не первый в команде, СА выполняет повторную проверку пригодности текущего "прямого" и "косвенного" объекта. Эта операция не требуется для первого "прямого" объекта в команде, поскольку она уже была выполнена на предыдущих стадиях обработки для всех объектов команды, и с тех пор в состоянии игры ничего не изменилось. Однако при обработке последующих объектов они могут стать непригодными вследствие изменений, произошедших при выполнении команды для первого объекта. Для выполнения повторной проверки пригодности СА вызывает определенный в глагольном объекте метод validDo для "прямого" и метод validIo для "косвенного" объекта. Если объект не прошел проверку пригодности, СА выводит сообщение об ошибке (используя метод cantReach объекта, если объект является видимым, либо используя сообщение об ошибке с кодом 38 - "Здесь больше этого не видно" - в противном случае) и прерывает выполнение команды.

  глагол.validDo(actor, directObject, 1)
  глагол.validIo(actor, indirectObject, 1)

После этого СА выполняет для текущих "прямого" и "косвенного" объектов описанную ниже серию вызовов методов.

Если один из перечисленных далее методов выполнит инструкцию abort, СА полностью прерывает обработку команды. Если одним из методов выполняется инструкция exit, СА сразу переходит к обработке функции postAction, а затем к обработке окончания хода, после чего возобновляет обработку оставшихся команд, если они введены игроком. Если один из этих методов использует инструкцию exitobj, СА пропустит все оставшиеся шаги по обработке только для текущего "прямого" объекта, сразу перейдя к функции postAction, после чего возобновит обработку текущей команды для последующих "прямых" объектов, если таковые имеются.

  глагол.verbAction(актер, прямой_объект, предлог, косвенный_объект);
  актер.actorAction(глагол, прямой_объект, предлог, косвенный_объект);
  актер.location.roomAction(актер, глагол, прямой_объект, предлог, косвенный_объект);

  if (косвенный_объект != nil)
  {
    косвенный_объект.iobjCheck(актер, глагол, прямой_объект, предлог);
    if (косвенный_объект не определяет в явном виде один из методов ioVerb или verIoVerb)
      косвенный_объект.iobjGen(актер, глагол, прямой_объект, предлог);
  }

  if (прямой_объект != nil)
  {
    прямой_объект.iobjCheck(актер, глагол, косвенный_объект, предлог);
    if (прямой_объект не определяет в явном виде один из методов doVerb или verDoVerb)
      прямой_объект.iobjGen(актер, глагол, косвенный_объект, предлог);
  }

  if (прямой_объект != nil && косвенный_объект != nil)
  {
    // если прямой_объект не определяет и не наследует метод verDoГлагол,
    // или если косвенный_объект не определяет и не наследует метод verIoГлагол,
    // вывести сообщение об ошибке ("Я не знаю как...") и закончить обработку

    if (для глагола установлен флаг [disambigDobjFirst])
      прямой_объект.verDoГлагол(актер);
    else
      прямой_объект.verDoГлагол(актер, косвенный_объект);

    // если метод verDoГлагол вывел какие-либо сообщения, закончить обработку

    if (для глагола установлен флаг [disambigDobjFirst])
      косвенный_объект.verIoГлагол(актер, прямой_объект);
    else
      косвенный_объект.verIoГлагол(актер);

    // если метод verIoГлагол вывел какие-либо сообщения, закончить обработку

    косвенный_объект.ioГлагол(актер, прямой_объект);
  }
  else if (прямой_объект != nil)
  {
    // если прямой_объект не определяет и не наследует метод verDoГлагол,
    // вывести сообщение об ошибке ("Я не знаю как...") и закончить обработку

    прямой_объект.verDoГлагол(актер);

    // если метод verDoГлагол вывел какие-либо сообщения, закончить обработку

    прямой_объект.doГлагол(актер);
  }
  else
  {
    Глагол.action(актер);
  }

Вне зависимости от того, каким образом завершилась описанная выше последовательность методов (успешным ли завершением всех методов, либо была прервана по инструкции exit, exitobj или abort), СА вызывает определенную в игровой программе функцию postAction:

  postAction(actor, verb, dobj, prep, iobj, status);

Аргумент status - это код, определяющий, каким образом завершилось выполнение команды:

EC_SUCCESS   Успешное завершение всех методов
EC_EXIT   Прерывание по инструкции exit
EC_EXITOBJ   Прерывание по инструкции exitobj
EC_ABORT   Прерывание по инструкции abort

Демоны и запалы

Если ни в одном из методов, вызывавшихся СА в процессе обработки, не встретилась инструкция abort, СА выполняет все активные демоны и запалы. Каждый из демонов выполняется один раз, а запалы, счетчик которых обнулился, также выполняются один раз, после чего удаляются.

endCommand

В заключение СА вызывает определенную в игре функцию endCommand():

    endCommand(actor, verb, dobj_list, prep, iobj, status);

Аргумент "status" имеет то же смысл, что и для функции postAction(). Другие аргументы имеют те же значения, что и при вызове функции preCommand() в начале цикла обработки команды.

СА вызывает функцию endCommand() для каждой команды, для которой начата стадия выполнения (т. е., иначе говоря, для всех команд, обработка которых не была завершена, скажем, из-за синтаксической ошибки или невозможности подбора объектов). СА вызывает эту функцию даже в том случае, если выполнение команды было завершено по инструкции exit, exitobj, или abort.


Общий обзор свойств, методов, объектов и функций

Как было описано ранее в настоящем Руководстве, СА вызывает определенные методы, которые могут определяться объектами в вашей игре, а также функции, которые также могут определяться в игровой программе. Подробное описание этих методов и функций приведено в других разделах Руководства. Здесь же приведен их общий краткий обзор без учета ряда тонких моментов их функционирования.


Свойства и методы


action(actor)

Определяется в глагольном объекте и вызывается на стадии выполнения команды для обработки команд без объектов.


actorAction(verb, dobj, prep, iobj)

Вызывается в объекте-актере на стадии выполнения команды.


adesc

Используется для отображения краткого описания объекта с неопределенным артиклем (в русском языке по понятным причинам не используется).


adjective

Определяет лексические свойства-прилагательные для объекта.


anyvalue(num)

СА вызывает этот метод для объектов с лексическим свойством-прилагательным, определяющим значение "#" (что соответствует любому числительному), когда игрок обращается к такому объекту с использованием слова "любой" в своей команде. Этот метод возвращает порядковый номер из допустимого диапазона номеров для данного объекта.


article

Определяет слова в качестве артиклей.


cantReach(actor)

Вызывается для "прямого" или "косвенного" объекта (только в случае, если одноименный метод не определен глагольным объектом) в случаях, когда объект виден, но недоступен; предполагается, что метод выводит сообщение, объясняющее игроку, почему команда невыполнима.


cantReach(actor, dolist, iolist, prep)

Вызывается для глагольного объекта, когда несколько объектов (аргумент dolist для "прямых" и iolist для "косвенных" объектов; при каждом вызове один из этих аргументов обязательно будет равен nil) видны, но недоступны; предполагается, что метод выводит сообщение, объясняющее игроку ситуацию.


construct

Вызывается сразу же после того, как создается новый объект при помощи оператора new. Этот метод должен по меньшей мере поместить созданный объект в список содержимого (contents) соответствующего объекта-контейнера.


contents

Список содержимого объекта.


ddesc

Краткое описание объекта в дательном падеже (используется только в RTADS).


destruct

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


disambigDobj(actor, prep, iobj, verprop, wordlist, objlist, flaglist, numberWanted, isAmbiguous, silent)

СА вызывает этот метод для глагольного объекта для того, чтобы разобрать словосочетание общего вида, использованное игроком в команде в качестве "прямого" объекта. СА вызывает этот метод для каждого такого словосочетания, вне зависимости от того, является ли это словосочетание однозначным или неопределенным.


disambigIobj(actor, prep, dobj, verprop, wordlist, objlist, flaglist, numberWanted, isAmbiguous, silent)

СА вызывает этот метод для глагольного объекта для того, чтобы разобрать словосочетание общего вида, использованное игроком в команде в качестве "косвенного" объекта. СА вызывает этот метод для каждого такого словосочетания, вне зависимости от того, является ли это словосочетание однозначным или неопределенным.


doAction

Это свойство определяется глагольным объектом, для которого задает шаблон команды с одним объектом и набор обработчиков для этого шаблона. Определенный этим свойством суффикс обработчика будет использоваться в названии метода-верификатора и метода-действия, определяемых "прямым" объектом (соответственно, verDoсуффикс и doсуффикс).


dobjCheck(actor, verb, iobj, prep)

Обобщенный метод-обработчик "прямого" объекта, вызываемый в процессе выполнения команды непосредственно перед тем, как СА обратится к методу dobjGen.


dobjGen(actor, verb, iobj, prep)

Обобщенный метод-обработчик "прямого" объекта, вызываемый в ходе выполнения команды для "прямого" объекта до того, как произойдет обращение к методу-верификатору и методу-действию этого объекта для глагола команды. СА не вызывает этот метод в том случае, если объект "замещает" его, определяя в явном виде (а не просто наследуя) метод-верификатор и/или метод-действие для текущего глагола (verDoГлагол или doГлагол).


doDefault(actor, prep, iobj)

Список "прямых" объектов по умолчанию; определяется глагольным объектом. Возвращает список объектов по умолчанию для данного глалола.


ioAction(prep)

Это свойство определяется глагольным объектом, для которого задает шаблон команды с двумя объектами для глагола с текущим предлогом, а также набор обработчиков для этого шаблона. Определенный этим свойством суффикс обработчика будет использоваться в названии метода-верификатора и метода-действия, определяемых "прямым" объектом (соответственно, verIoсуффикс и ioсуффикс).


iobjCheck(actor, verb, iobj, prep)

Обобщенный метод-обработчик "косвенного" объекта, вызываемый в процессе выполнения команды непосредственно перед тем, как СА обратится к методу iobjGen.


iobjGen(actor, verb, dobj, prep)

Обобщенный метод-обработчик "косвенного" объекта, вызываемый в ходе выполнения команды для "косвенного" объекта до обращения к методу-верификатору и методу-действию данного объекта для глагола текущей команды. СА не вызывает этот метод, если объект "замещает" его, определяя в явном виде (а не просто наследуя) метод-верификатор и/или метод-действие для текущего глагола (verIoГлагол или ioГлагол).


ioDefault(actor, prep)

Список "косвенных" объектов по умолчанию; определяется глагольным объектом. Возвращает список соответствующих объектов по умолчанию для данного глагола.


isEquivalent

Используется для того, чтобы определить, следует ли считать объект неотличимым от других объектов, принадлежащих тому же непосредственному родительскому классу. Если данное свойство имеет значение true, СА считает, что все объекты, принадлежащие тому же непосредственному родительскому классу, что и данный объект, могут заменяться друг на друга в процессе устранения неопределенности.


isHim

Если это свойство имеет значение true, то объект имеет мужской род и может заменяться местоимением "он" (и его падежными формами). Установка этого свойства оказывает влияние также на ряд ответов по умолчанию, определяемых в файле advr.t.


isHer

Если это свойство имеет значение true, то объект имеет женский род и может заменяться местоимением "она" (и его падежными формами). Установка этого свойства оказывает влияние также на ряд ответов по умолчанию, определяемых в файле advr.t.


isThem

Добавлено в версии TADS 2.5.2

Если данное свойство имеет значение true, объект имеет множественное число и может заменятьс местоимением "они" (и его падежными формами). Установка этого свойства оказывает влияние также на ряд ответов по умолчанию, определяемых в файле advr.t. Другими словами, СА использует свойство isThem для того, чтобы принять решение о том, какое местоимение необходимо отображать при запросе "косвенного" объекта. До версии TADS 2.5.2 СА различал только свойства isHim и isHer и, если ни одно из них не было установлено, использовал местоимение "оно", "это". Начиная с версии 2.5.2 СА использует местоимение "они", если все подобранные объекты определяют свойство isThem равным true. В RTADS функция для вывода запроса по устранению неопределенности переопределена, но в ней анализируются те же самые свойства и по тому же принципу.


isVisible(vantage)

Используется, чтобы определить, виден ли объект для другого объекта. СА использует этот метод, чтобы определить, каким образом сообщить игроку о недостижимости объекта: если объект виден, но недоступен, для этого используется метод cantReach; в противном случае будет выведено сообщение "Я не вижу здесь этого".


location

Местоположение объекта, т. е. другой объект, содержащий его.


locationOK

Устанавливая это свойство равным true, автор игры сообщает компилятору, что он в курсе того, что свойство location того же объекта не ссылается на объект. Если этого не сделать, компилятор в таких случаях выдаст соответствующее предупреждение.


multisdesc

Используется СА для того, чтобы отобразить название текущего объекта в случаях, когда он отрабатывает команду с несколькими "прямыми" объектами. Обратите внимание, что СА не будет обращаться к этому методу, если для объекта определен метод prefixdesc.


newNumbered(actor, verb, num)

СА вызывает данный метод для объектов, определяющих обобщенное лексическое свойство-числительное (adjective = '#') в случаях, когда игрок использует такой объект в составе словосочетания с числительным в своей команде. Метод возвращает объект, который будет считаться подобранным по данному словосочетанию (иначе говоря, будет подставлен в команду вместо словосочетания); аргумент num соответствует использованному игроком в команде числительному (например, для команды "открыть ячейку 55" аргумент num будет равен числу 55).


nilPrep

Данное свойство определяется в глагольном объекте и используется СА для того, чтобы определить, какой предлог следует использовать для команд без предлога (вида ГЛАГОЛ-"ПРЯМОЙ" ОБЪЕКТ-"КОСВЕННЫЙ" ОБЪЕКТ). Если свойство не определено, СА использует по умолчанию предлог, соответствующий слову "to". В RTADS этот механизм не используется.


noun

Определяет лексические свойства-существительные для объекта.


parseUnknownDobj(actor, prep, iobj, wordlist)

СА вызывает данный метод для подбора "прямого" объекта для словосочетания (составляющие словосочетание лексемы передаются при помощи аргумента wordlist), содержащего неизвестные слова. Метод вызывается для глагольного объекта, соответствующего глаголу текущей команды.


parseUnknownIobj(actor, prep, iobj, wordlist)

СА вызывает данный метод для подбора "косвенного" объекта для словосочетания (составляющие словосочетание лексемы передаются при помощи аргумента wordlist), содержащего неизвестные слова. Метод вызывается для глагольного объекта, соответствующего глаголу текущей команды.


pdesc

Краткое описание объекта в предложном падеже (используется только в RTADS).


plural

Лексические свойство множественного числа для объекта.


pluraldesc

Выводит описание объекта во множественном числе. СА и ряд служебных функций, определенных в advr.t, используют это свойство для описания группы неразличимых объектов (например, "пять золотых монет").


preferredActor

Используется СА, чтобы определить, является ли объект "предпочтительным" актером; если данное свойство имеет значение true, данный объект используется в качестве актера в случаях, когда обращение к актеру в команде неоднозначно, а для всех остальных доступных объектов это свойство имеет значение nil.


prefixdesc(show, current_index, count, multi_flags)

Вызывается СА до начала фазы выполнения для каждого "прямого" объекта, задействованного в команде, для того, чтобы отобразить описание объекта перед отображением результатов применения к нему команды. СА вызывает этот метод для всех "прямых" объектов в команде независимо от того, использован ли в команде один такой объект или несколько. Если для объекта определены методы prefixdesc и multisdesc, СА вызывает только первый из них.


prepDefault

Определяется глагольным объектом. СА использует это свойство с целью определения объекта-предлога, используемого по умолчанию, в случаях, когда игрок вводит неполную команду, содержащую только глагол и "прямой" объект (т. е. предлог и "косвенный" объект пропущены).


preposition

Лексическое свойство-предлог.


rdesc

Краткое описание объекта в родительном падеже (используется только в RTADS).


rejectMultiDobj(prep)

Определяется глагольным объектом. Если данный метод возвращает true, с глаголом нельзя использовать несколько "прямых" объектов или слово "все".


roomAction(actor, verb, dobj, prep, iobj)

Вызывается в процессе фазы выполнения команды для объекта-локации игрока.


roomCheck(verb)

Вызывается для объекта-актера перед фазой подбора объектов.


sdesc

Краткое описание. Используется СА для отображения названия объекта.


statusLine

Вызывается для объекта-локации игрока с целью обновления информации в строке состояния.


tdesc

Краткое описание объекта в творительном падеже (используется только в RTADS).


thedesc

Выводит название объекта с определенным артиклем (в RTADS не используется).


validActor

Вызывается СА для того, чтобы определить, пригоден ли данный объект в качестве актера. Метод не проверяет, будет ли логичным обратиться к объекту как к актеру, а лишь сообщает, является ли объект доступным для отдачи ему команд.


validDo(actor, obj, seqno)

Определяется в глагольном объекте. Возвращает true, если объект obj является доступным в качестве "прямого" для данного глагола.


validDoList(actor, prep, iobj)

Определяется в глагольном объекте. Возвращает список объектов, которые потенциально пригодны для использования в качестве "прямых". Объекты из этого списка будут проверяться еще раз посредством метода validDo, поэтому список может содержать и некоторое количество непригодных объектов - главное, чтобы validDoList не отбрасывал заведомо пригодные объекты.


validIo(actor, obj, seqno)

Определяется в глагольном объекте. Возвращает true, если объект obj является доступным в качестве "косвенного" для данного глагола.


validIoList(actor, prep, dobj)

Определяется в глагольном объекте. Возвращает список объектов, которые потенциально пригодны для использования в качестве "косвенных". Объекты из этого списка будут проверяться еще раз посредством метода validIo, поэтому список может содержать и некоторое количество непригодных объектов - главное, чтобы validIoList не отбрасывал заведомо пригодные объекты.


value

Для объекта-строки (strObj) и объекта-числа (numObj) СА устанавливает это свойство равным соответствующему строковому или числовому значению, введенному игроком.


verb

Лексическое свойство-глагол. Строковые значения, определенные в этом свойстве, могут состоять из одного или двух слов; если строковое значение состоит из двух слов, второе слово должно быть определено отдельно в качестве предлога.


verbAction(actor, dobj, prep, iobj)

СА вызывает данный метод глагольного объекта в процессе выполнения команды непосредственно перед вызовом метода actorAction для объекта-актера текущей команды.


vdesc

Краткое описание объекта в винительном падеже (используется только в RTADS).


Объекты


againVerb

Глагольный объект с лексическими свойствами, соответствующий повтору предыдущей команды. При вводе команды "повтор" СА организует вызов предыдущей команды, используя свой внутренний алгоритм.


Me

Объект, соответствующий главному персонажу по умолчанию. Если команда явным образом не обращена к другому актеру, то ее обрабатывает именно данный объект. Следует отметить, что в данном случае речь идет именно о главном персонаже по умолчанию; автор игры может изменить его, используя встроенную функцию parserSetMe().


numObj

Специальный объект, используемый в качестве "прямого" или "косвенного", если игрок ввел в своей команде число (например, "набрать 25 на калькуляторе" - numObj будет "прямым" объектом; "установить регулятор на 16" - "косвенным"). Свойство value этого объекта будет принимать значение, равное числу, введенному в команде.


strObj

Специальный объект, используемый в качестве "прямого" или "косвенного", если игрок ввел в своей команде строку в кавычках (например, "набрать "Привет!" на клавиатуре" - здесь strObj будет "прямым" объектом). Свойство value этого объекта будет принимать значение строки, введенной в команде.


takeVerb

В более ранних версиях TADS определение глагольного объекта с таким названием было необходимостью, однако в настоящее время напрямую определение этого глагола синтаксическим анализатором не используется.


Функции


commandPrompt(type)

Если эта функция определена, СА вызывает ее, чтобы вывести приглашение на ввод. Аргумент type является кодом типа информации, которую запрашивает СА: 0 соответствует обычной команде; 1 - команда, вводимая после того, как СА "пожаловался" на неизвестные слова в предыдущей команде; 2 - информация, вводимая в ответ на запрос по устранению неопределенности; 3 - информация, вводимая в ответ на запрос "прямого" объекта; 4 - то же самое, для "косвенного" объекта.


commandAfterRead(type)

СА вызывает данную функцию (если она определена) сразу же после того, как игрок завершил ввод информации или команды. Данная функция, в частности, может отменять все эффекты по форматированию текста, которые активировала commandPrompt перед выводом приглашения на ввод. Аргумент type имеет тот же смысл, что и для commandPrompt.

Функция введена специально для того, чтобы облегчить использование текстовых эффектов для текста, вводимого игроком; особенно полезной она будет при использовании возможностей HTML-TADS. Например, если commandPrompt установила для приглашения на ввод и текста команды некое специальное форматирование (тип/размер шрифта, цвет), то commandAfterRead позволит отменить их сразу после того, как игрок ввел свой текст, и вся дальнейшая информация будет выводиться как обычно. Поскольку commandPrompt и commandAfterRead всегда вызываются попарно, автор игры всегда может быть уверен в том, что эффекты, заданные в commandPrompt, смогут быть отменены в commandAfterRead.


endCommand(actor, verb, dobj_list, prep, iobj, status)

Если функция с таким названием определена, СА вызывает ее после выполнения всех действий по обработке команды, включая вызов демонов и запалов.


init()

Данная функция вызывается сразу же после запуска игры, а также каждый раз при ее перезапуске. Данная функция может выполнять все необходимые действия по инициализации (например, установку демонов и запалов, вывод начального текста игры и т. п.). Обратите внимание, что система не вызывает init(), когда игрок вызывает интерпретатор TADS и указывает в командной строке (или иным способом), что требуется восстановить игру. В этом случае вызывается функция initRestore() (впрочем, если последняя не определена, система вызывает init() и в этом случае).


initRestore(savedGameFileName)

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


pardon

СА вызывает эту функцию, если игрок введ пустую команду. Как правило, она просто выводит соответствующее сообщение об ошибке.


parseAskobj(verb, ...)

СА вызывает эту функцию, если она определена, чтобы запросить пропущенный в команде "прямой" или "косвенный" объект. Если определена функция parseAskobjActor, СА игнорирует функцию parseAskobj. Если при вызове функции передается два аргумента, это значит, что запрашивается "косвенный" объект (второй аргумент в этом случае является предллогом и может быть равен nil); если один, то "прямой".


parseAskobjActor(actor, verb, ...)

Если данная функция определена, СА вызывает ее для вывода запроса игроку на "прямой" или "косвенный" объект, пропущенный в команде. Если заданы три аргумента, запрашивается "косвенный" объект, а третий аргумент является объектом-предлогом (может быть равен nil); в противном случае запрашивается "прямой" объект.


parseAskobjIndirect(actor, verb, prep, objectList)

Если данная функция определена в игровой программе, СА вызывает ее для вывода запроса игроку на пропущенный в команде "косвенный" объект. Эта функция используется СА в первую очередь; только если она не определена, СА обращается к parseAskobjActor() или parseAskobj().


parseDefault(obj, prep)

СА вызывает данную функцию (если таковая определена), чтобы вывести сообщение о том, что некий объект (или предлог, если последний не равен nil), не упомянутый в команде игрока, будет использован по умолчанию.

Начиная с версии TADS 2.5.8 вместо данной функции может использоваться функция parseDefaultExt с расширенным набором аргументов.


parseDefaultExt(actor, verb, obj, prp)

Данная функция замещает parseDefault() в версиях TADS 2.5.8 и более поздних. В RTADS определены и parseDefault(), и parseDefaultExt() (для разных версий компилятора). По существу, parseDefaultExt() дублирует свою предшественницу, за исключением того, что позволяет более точно подобрать падеж объекта в случае, когда объект-предлог равен nil (в RTADS parseDefault() в этом случае всегда использует винительный падеж, что не вполне корректно).


parseDisambig(nameString, objList)

Если данная функция определена, СА обращается к ней, чтобы вывести запрос о дополнительной информации в том случае, если игрок использует в своей команде неоднозначное обращение к объекту. Аргумент nameString - это строка, соответствующая введенному игроком обращению к объекту (представленному в виде строкового значения в одинарных кавычках), а objList - это список объектов, которые были подобраны для этого обращения.


parseError(num, str)

Если данная функция определена, СА вызывает ее, чтобы получить текст сообщения об ошибке. Аргумент num - это код сообщения об ошибке, а str - текст сообщения, который СА отобразил бы по умолчанию. Если в игре определена функция parseErrorParam, СА никогда не обращается к данной функции. В RTADS функция parseError определена.


parseErrorParam(num, str, ...)

Если данная функция определена, СА обращается к ней для формирования текста сообщения об ошибке. Аргумент num соответствует коду сообщения об ошибке, str - тексту сообщения по умолчанию, а остальные аргументы определяют значения, подставляемые вместо форматных символов "%s" (для строковых значений) и "%d" (для числовых значений) в тексте сообщения по умолчанию. В RTADS данная функция не определена.


parseError2(verb, dobj, prep, iobj)

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


parseNounPhrase(wordlist, typelist, currentIndex, complainOnNoMatch, isActorCheck)

Если функция определена, СА вызывает ее для обработки каждого словосочетания. Это позволяет автору игры назначать специальный алгоритм разбора для определенных словосочетаний; если этого не требуется, функция просто предоставит СА разобрать словосочетание по стандартному алгоритму. В RTADS данная функция определена.


parseUnknownVerb(actor, wordlist, typelist, errnum)

Если данная функция определена, СА вызывает ее для обработки фразы, которую он не смог распознать. Говоря конкретнее, СА обращается к этой функции в случае, если в команде отсутствует глагол или если структура команды не соответствует набору шаблонов, распознаваемых СА. В RTADS данная функция не определена.


postAction(actor, verb, dobj, prep, iobj, status)

Если данная функция определена, СА вызывает ее в конце фазы выполнения. Если команда содержит несколько "прямых" объектов, СА вызывает эту функцию по одному разу для каждого из них. Функция вызывается даже в том случае, если выполнение команды прерывается по инструкции exit, exitobj или abort.


preCommand(actor, verb, dobj_list, prep, iobj)

Если данная функция определена, СА вызывает ее в начале фазы выполнения команды (т. е. после того, как удалось подобрать все объекты для слов/словосочетаний команды). В RTADS эта функция не определена.


preinit

Данная функция вызывается компилятором после окончания процесса компиляции в целях выполнения неких действий по инициализации. Функция не может устанавливать демоны и запалы, а также выводить сообщения, поскольку эти действия не сохраняются в откомпилированном файле, а вызываются в ходе выполнения игры. Основное назначение функции preinit() - выполнение ресурсоемких операций (например, инициализация списков объектов и/или присвоение начальных значений свойствам), которые в противном случае выполнялись бы каждый раз при инициализации игры в ходе выполнения функции init(). За счет переноса этих действий в preinit() мы добиваемся того, что они (т. е. действия) выполняются один раз при компиляции игры, что впоследствии сократит время ее запуска, а следовательно, повысит комфорт для игрока. Обратите внимание, что если игра откомпилирована в режиме отладки, данная функция будет вызываться в процессе выполнения игры. За исключением увеличения задержки при запуске, это никак не отразится на поведении игры; взамен автор игры получит возможность трассировать код preinit() при помощи отладчика. В стандартном TADS (и RTADS) данная функция осуществляет инициализацию списков всех источников света в игре, а также всех скрытых объектов (т. е. тех, для обнаружения которых игроку требуется тем или иным способом обыскать объект-контейнер).


preparse(cmd)

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


preparseCmd(wordList)

Если данная функция определена в игре, СА вызывает ее перед началом подбора объектов, передавая ей в качестве аргумента список строковых значений, которые соответствуют отдельным словам (лексемам) введенной игроком команды. Если игрок ввел "пачку" из нескольких команд, то функция вызывается для каждой отдельной команды. Функция может вернуть либо true (переданный список лексем остается без изменений, его обработка продолжается "умолчальными" средствами СА), либо nil (команда отбрасывается), либо новый список лексем (в этом случае исходный список заменяется возвращенным, и СА возвращается к шагу предварительного подбора объектов). Новый список строковых значений функция может вернуть только один раз; если при повторной обработке возвращенного ею списка она вновь вернет список значений, возникнет ошибка выполнения. В RTADS данная функция определена.


preparseExt(actor, verb, str, typ)

Начиная с версии TADS 2.5.8, эта функция (если она определена) будет автоматически вызываться СА вместо preparse() в случаях, когда игрок вводит текст в ответ на уточняющий запрос игры или после сообщения об ошибке вида "Я не знаю слова...". По сравнению с preparse()она имеет расширенный список аргументов (дополнительно к введенной игроком строке передаются текущие актер, глагол, а также тип запроса - например, ввод после команды с неизвестным словом, после неполной/неоднозначной команды и т. п.). Может вернуть строковое значение - в этом случае СА попытается интерпретировать его в качестве ответа на запрос вместо исходного; true - при этом СА будет пытаться интерпретировать в качестве ответа на запрос исходную строку, введенную игроком; или nil - в этом случае введенная игроком строка будет считаться новой командой, и СА не будет предпринимать попыток интерпретировать ее в качестве ответа на свой запрос. В RTADS данная функция определена.


Блок-схема алгоритма разбора

Блок-схему алгоритма разбора предложения можно посмотреть здесь (необходим Adobe Acrobat Reader версии 5.0 или выше, размер файла ок. 900 кбайт).

Справочная таблица по "точкам входа"

Ниже приведена справочная таблица по "точкам входа", доступным для модификации синтаксического анализатора, с кратким описанием. Функции приведены в том порядке, в каком они вызываются в процессе обработки.

Наименование Когда вызывается Файл, в котором определена* Что делает в RTADS*
commandPrompt при выводе приглашения на ввод stdr.t устанавливает стандартный шрифт ввода TADS; дублирует системное приглашение на ввод; при снятии комментария выводит приглашение для начинающих
commandAfterRead сразу после считывания ввода игрока stdr.t переключается со шрифт ввода на обычный шрифт по умолчанию
preparse сразу после commandAfterRead при обычном вводе advr.t замена во введенной строке "ё" на "е"; перевод строки в нижний регистр; замена строки "и" на "инвентарь"
preparseExt сразу после commandAfterRead при корректирующем вводе advr.t см. preparse; кроме того, обеспечивает распознавание корректирующей команды "ой" и комментариев
pardon в случае пустого ввода игрока stdr.t выводит "Вы что-то сказали?"
parseErrorParam при выводе сообщения об ошибке - -
parseError при выводе сообщения об ошибке, если не определена parseErrorParam errorru.t формирует сообщение об ошибке на русском языке
parseDisambig при запросе игроку errorru.t формирует запрос игроку (о том, какой объект тот имел в виду) на русском языке
parseNounPhrase перед началом процесса стандартного разбора словосочетания advr.t разбирает словосочетания со словом "себя"; осуществляет предварительный подбор словосочетаний, где существительное-определение следует за определеяемым (например, "берег реки")
parseUnknownVerb перед началом процесса стандартного разбора словосочетания, если вместо глагола - неизвестное слово, либо невозможно определить формат команды - -
preparseCmd перед началом процесса стандартного разбора словосочетания, но после вызова parseNounPhrase advr.t приводит команду к одному из шаблонов, понятных встроенному синтаксическому анализатору
parseAskobjIndirect при запросе "косвенного" объекта у игрока - -
parseAskobjActor при запросе у игрока "прямого" объекта (или "косвенного", если не определена parseAskobjIndirect) errorru.t формирует запрос объекта у игрока в зависимости от введенной команды, в соответствии с правилами русского языка
parseAskobj при запросе у игрока "прямого" или "косвенного" объекта, если не определены parseAskobjIndirect и parseAskobjActor - -
parseDefaultExt в случаях, если синтаксическому анализатору удалось подобрать "прямой" или "косвенный" объект самостоятельно (начиная с версии TADS 2.5.8) errorru.t выводит название подобранного СА объекта с учетом падежа
parseDefault в случаях, если синтаксическому анализатору удалось подобрать "прямой" или "косвенный" объект самостоятельно (для версий TADS более ранних, чем 2.5.8) errorru.t выводит название подобранного СА объекта с учетом падежа
preCommand после подбора всех объектов, перед началом выполнения команды - -
parseError2 при выполнении команды, если для объекта не определен соответствующий метод-верификатор errorru.t формирует сообщение об ошибке в соответствии с правилами русского языка
postAction после выполнения команды, перед вызовом демонов и запалов - -
endCommand после выполнения демонов и запалов, а также при завершении команды по инструкции abort - -

- Глупец! - прервал его Рафаэль. - Попробуй и дальше так себя сокращать - и ты создашь целые тома!
ОНОРЕ ДЕ БАЛЬЗАК (HONORE DE BALZAC), Шагреневая кожа (1831)


Раздел 4.3 Содержание Глава 5