exponenta event banner

Чтение файлов записей с TLC

Обзор учебного пособия

Цель: Понять структуру файлов записей и научиться анализировать их с помощью директив TLC.

Папка: matlabroot/toolbox/rtw/rtwdemos/tlctutorial/guide (открыто)

В этом учебном пособии рассматривается простой файл структурированных записей с серией сценариев TLC. Вы узнаете, как структурированы записи и как TLC %assign и %<> для их обработки используются директивы расширения маркеров. Кроме того, в учебном пособии показаны циклы с использованием %foreachи определение области с использованием %with.

Учебное пособие включает следующие шаги, которым необходимо следовать последовательно:

  1. Структура файлов записей - некоторые фоновые и простые примеры

  2. Интерпретировать записи - представление содержимого файла записи

  3. Анатомия сценария TLC - деконструкция презентации

  4. Изменить read-guide.tlc - Эксперимент с ТСХ

  5. Передать и использовать параметр - передать параметры из командной строки в файлы TLC

  6. Обзор

Структура файлов записей

Генератор кода компилирует модели в структурированную форму, называемую файлом записи, называемую model.rtw. Такие скомпилированные файлы модели аналогичны по синтаксису и организации файлам исходных моделей, поскольку содержат ряд иерархически вложенных записей формы.

recordName {itemName itemValue}

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

В model.rtw файл, имя записи верхнего уровня (первой): CompiledModel. Каждый блок представляется субзаписью внутри него, идентифицируемой именем блока. TLC может анализировать хорошо сформированные файлы записей, как показано в этом упражнении.

Следующий список является допустимым файлом записи, который может быть проанализирован TLC, но не для которого он может создать код. Комментарии обозначаются знаком фунта (#):

# 
# File: guide.rtw	Illustrative record file, which can't be used by Simulink
#                                     Note: string values MUST be in quotes
Top {                               # Outermost Record, called Top
  Date         "21-Aug-2008"        # Name/Value pair named Top.Date
  Employee {                        # Nested record within the Top record
    FirstName  "Arthur"             #   Alpha field Top.Employee.FirstName
    LastName   "Dent"               #   Alpha field Top.Employee.LastName
    Overhead    1.78                #   Numeric field Top.Employee.Overhead
    PayRate     11.50               #   Numeric field Top.Employee.PayRate
    GrossRate   0.0                 #   Numeric Field Top.Employee.GrossRate
  }                                 # End of Employee record
  NumProject   3                    # Indicates length of following list
  Project {                         # First list item, called Top.Project[0]
    Name       "Tea"                #   Alpha field Name, Top.Project[0].Name
    Difficulty 3                    #   Numeric field Top.Project[0].Difficulty
  }                                 # End of first list item
  Project {                         # Second list item, called Top.Project[1]
    Name       "Gillian"            #   Alpha field Name, Top.Project[1].Name
    Difficulty 8                    #   Numeric field Top.Project[1].Difficulty
  }                                 # End of second list item
  Project {                         # Third list item, called Top.Project[2]
    Name       "Zaphod"             #   Alpha field Name, Top.Project[2].Name
    Difficulty 10                   #   Numeric field Top.Project[2].Difficulty
  }                                 # End of third list item
}                                   # End of Top record and of file

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

Интерпретировать записи

Вот выходные данные скрипта программы TLC, который считывает guide.rtw, интерпретирует его записи, обрабатывает полевые данные и форматирует описания, которые направляются в командное окно MATLAB ®:

Using TLC you can:
* Directly access a field's value, e.g.
  %<Top.Date> -- evaluates to:
  "21-Aug-2008"
  
* Assign contents of a field to a variable, e.g.
  "%assign worker = Top.Employee.FirstName"
  worker expands to Top.Employee.FirstName = "Arthur"

* Concatenate string values, e.g.
  "%assign worker = worker + " " + Top.Employee.LastName"
  worker expands to worker + " " + Top.Employee.LastName = "Arthur Dent"
  
* Perform arithmetic operations, e.g.
  "%assign wageCost = Top.Employee.PayRate * Top.Employee.Overhead"
  wageCost expands to Top.Employee.PayRate * Top.Employee.Overhead <- 11.5 * 1.78 = 20.47
  
* Put variables into a field, e.g.
  Top.Employee.GrossRate starts at 0.0
  "%assign Top.Employee.GrossRate = wageCost"
  Top.Employee.GrossRate expands to wageCost = 20.47

* Index lists of values, e.g.
  "%assign projects = Top.Project[0].Name + ", " + Top.Project[1].Name..."
  "+ ", " + Top.Project[2].Name"
  projects expands to Top.Project[0].Name + ", " + Top.Project[1].Name
  + ", " + Top.Project[2].Name = Tea, Gillian, Zaphod

* Traverse and manipulate list data via loops, e.g.
  - At top of Loop, Project = Tea; Difficulty = 3
  - Bottom of Loop, i = 0; diffSum = 3.0
  - At top of Loop, Project = Gillian; Difficulty = 8
  - Bottom of Loop, i = 1; diffSum = 11.0
  - At top of Loop, Project = Zaphod; Difficulty = 10
  - Bottom of Loop, i = 2; diffSum = 21.0
  Average Project Difficulty expands to diffSum / Top.NumProject = 21.0 / 3 = 7.0

Этот вывод из guide.rtw был создан путем вызова TLC из окна команд MATLAB, выполнения сценария с именем read-guide.tlc. Сделайте это самостоятельно, выполнив следующие действия:

  1. В MATLAB измените папку (cd) на вашу копию tlctutorial/guide в рабочей папке.

  2. Для получения только что перечисленных выходных данных выполните guide.rtw со сценарием TLC read-guide.tlc путем ввода следующей команды:

    tlc -v -r guide.rtw read-guide.tlc

Использование команды Note:

  • -r коммутатор (для чтения) идентифицирует файл входных данных, в данном случае guide.rtw.

  • Сценарий TLC, обрабатывающий файл данных, определяется последним введенным маркером.

  • -v switch (для подробных данных) направляет выходные данные в окно команд, если только TLC-файл не обрабатывает их сам.

Анатомия сценария TLC

Теперь вы рассекаете сценарий, который только что запустили. Каждый «параграф» выходных данных guide.tlc рассматривается последовательно в следующих кратких разделах:

Соглашения по кодированию

Ниже приведены некоторые основные положения о синтаксисе и кодировании TLC:

%% Comment Комментарий TLC, который не выводится
/* comment */ Комментарий, для вывода
%keyword Директива TLC (ключевое слово), начните с "%
%<expr>Оператор TLC-маркера
. (период) Оператор объема, например, Top.Lev2.Lev3
... (в конце строки) Продолжение инструкции (разрыв строки не выводится)
\ (в конце строки)Продолжение инструкции (вывод разрыва строки)
localvarIdentifier Локальные переменные начинаются в нижнем регистре
GlobalvarIdentifier Глобальные переменные начинаются в верхнем регистре
RecordIdentifier Идентификаторы записей начинаются в верхнем регистре
EXISTS() Встроенные функции TLC именуются в верхнем регистре
Примечание.TLC-идентификаторы чувствительны к регистру.

Для получения дополнительной информации см. Соглашения по кодированию TLC.

Заголовок файла

Файл read-guide.tlc начинается с:

%% File: read-guide.tlc   (This line is a TLC Comment, and will not print)
%% 
%% To execute this file, type: tlc -v -r guide.rtw read-guide.tlc
%% Set format for displaying real values (default is "EXPONENTIAL")
%realformat "CONCISE"
  • Строки с 1 по 4 - текст в строке, следующей за символами %% рассматривается как комментарий (игнорируется, не интерпретируется или выводится).

  • Строка 5 - как поясняется в тексте четвертой строки, является директивой TLC (ключевое слово) %realformat, который управляет форматированием последующих чисел с плавающей запятой при выводе на экран. Здесь мы хотим минимизировать отображаемые цифры.

Расширение маркера

Первый раздел выходных данных создается строками сценария:

Using TLC you can:
* Directly access a field's value, e.g.
%assign td = "%" + "<Top.Date>"
  %<td> -- evaluates to:
  "%<Top.Date>"
  • Строки 1 и 2 - (и строки, не содержащие директив или маркеров TLC) просто перекликаются с выходным потоком, включая начальные и конечные пробелы.

  • Строка 3 - создание переменной с именем td и присваивает строковое значение %<Top.Date> к нему. %assign создает новые и изменяет существующие переменные. Его общий синтаксис:

    %assign ::variable = expression
    Необязательный префикс двойной двоеточия указывает, что переменная, которой назначается, является глобальной переменной. При его отсутствии TLC создает или изменяет локальную переменную в текущей области.

  • Строка 4 - Отображение

    %<Top.Date> -- evaluates to:
    Предыдущая строка позволяет TLC печатать %<Top.Date> не расширяя его. Он создает строку, вставляя два литерала.
    %assign td = "%" + "<Top.Date>"
    Как обсуждалось в String Processing Plus, оператор plus объединяет строки как и добавляет числа, векторы, матрицы и записи.

  • Строка 5 - Оценка (расширение) записи Top.Date. Точнее, он оценивает поле Date который существует в области действия Top. Синтаксис %<expr> вызывает выражение expr (которая может быть записью, переменной или функцией), подлежащей оценке. Эту операцию иногда называют оценочной.

Примечание

Вы не можете вложить %<expr> оператор (то есть %<foo%<bar>> не допускается).

Примечание

При использовании %<expr> оператор в кавычках, например, "%<Top.Date>"TLC расширяет выражение, а затем заключает результат в кавычки. Однако размещение %assign в кавычках, например, "%assign foo = 3", просто повторяет оператор, заключенный в кавычки к выходному потоку. Нет результатов присвоения (значение foo остается неизменным или неопределенным).

Общее назначение

Второй раздел выходных данных создается строками сценария:

* Assign contents of a field to a variable, e.g.
%assign worker = Top.Employee.FirstName
  "%assign worker = Top.Employee.FirstName"
  worker expands to Top.Employee.FirstName = %<worker>
  • Строка 1 - эхо-сигнал на выходе.

  • Строка 2 - Присвоение поля FirstName в Top.Employee запись области в новую локальную переменную с именем worker.

  • Строка 3 - повторяет предыдущую инструкцию, создавая выходные данные, заключая их в кавычки.

  • Строка 4 - поясняет следующее назначение и иллюстрирует расширение маркера. Символ %<worker> расширяется до Arthur.

Обработка строк плюс

Следующий раздел сценария иллюстрирует конкатенацию строк, одно из применений "+"оператор:

* Concatenate string values, e.g.
%assign worker = worker + " " + Top.Employee.LastName
  "%assign worker = worker + " " + Top.Employee.LastName"
  worker expands to worker + " " + Top.Employee.LastName = "%<worker>"
  • Строка 1 - эхо-сигнал на выходе.

  • Строка 2 - выполняет конкатенацию.

  • Линия 3 - эхо линии 2 на выход.

  • Строка 4 - описывает операцию, в которой переменная связывается с полем, разделенным символом пробела. Альтернативный способ сделать это без использования + оператор, является

    %assign worker = "%<Top.Employee.FirstName> %<Top.Employee.LastName>"
    Альтернативный метод использует оценки полей и является одинаково эффективным.

+ оператор, который является ассоциативным, также работает для числовых типов, векторов, матриц и записей:

  • Числовые типы (Numeric Types) - добавление двух выражений вместе; оба операнда должны быть числовыми. Например:

    Выходные данные:
    * Numeric Type example, e.g.
      Top.Employee.PayRate = 11.5
      Top.Employee.Overhead = 1.78
      td = Top.Employee.PayRate + Top.Employee.Overhead
      td evaluates to 13.28

  • Векторы - если первый аргумент является вектором, а второй - скалярным значением, TLC добавляет скалярное значение к вектору. Например:

    Выходные данные:
    * Vector example, e.g.
      v1 is [0, 1, 2, 3]
      Top.Project[1].Difficulty is 8
      v2 = v1 + Top.Project[1].Difficulty
      v2 evaluates to: [0, 1, 2, 3, 8]

  • Матрицы - если первый аргумент является матрицей, а второй является вектором той же ширины столбца, что и матрица, TLC добавляет вектор в качестве другой строки к матрице. Например:

    Выходные данные:
    * Matrices example, e.g.
      mx1 is [ [4, 5, 6, 7]; [8, 9, 10, 11] ]
      v1 is [0, 1, 2, 3]
      mx = mx1 + v1
      mx evaluates to [ [4, 5, 6, 7]; [8, 9, 10, 11]; [0, 1, 2, 3] ]

  • Записи - если первый аргумент является записью, TLC добавляет второй аргумент в качестве идентификатора параметра (с его текущим значением). Например:

    Выходные данные:
    * Record example, e.g.
      StartDate is August 28, 2008 
      Top + StartDate
      Top.StartDate evaluates to August 28, 2008

Арифметические операции

TLC обеспечивает полное дополнение арифметических операторов для числовых данных. В следующей части нашего сценария TLC умножаются два числовых поля:

* Perform arithmetic operations, e.g.
%assign wageCost = Top.Employee.PayRate * Top.Employee.Overhead
  "%assign wageCost = Top.Employee.PayRate * Top.Employee.Overhead"
  wageCost expands to Top.Employee.PayRate * Top.Employee.Overhead ...
 <- %<Top.Employee.PayRate> * %<Top.Employee.Overhead> = %<wageCost>
  • Строка 1 - эхо-сигнал на выходе.

  • Линия 2 - %assign оператор, вычисляющий значение, которое TLC сохраняет в локальной переменной wageCost.

  • Строка 3 - перекликается с операцией в строке 2.

  • Строки 4 и 5 - Составьте один оператор. Многоточие (вводится как три последовательных периода, например: ... ) сигнализирует, что оператор продолжается в следующей строке, но если оператор имеет выход, TLC не вставляет разрыв строки. Чтобы продолжить инструкцию и вставить разрыв строки, замените многоточие обратной косой чертой (\).

Изменить записи

После считывания в память можно изменять записи и управлять ими подобно переменным, создаваемым путем назначения. Следующий сегмент read-guide.tlc заменяет значение поля записи Top.Employee.GrossRate:

* Put variables into a field, e.g.
%assign Top.Employee.GrossRate = wageCost
  "%assign Top.Employee.GrossRate = wageCost"
  Top.Employee.GrossRate expands to wageCost = %<Top.Employee.GrossRate>

Такие изменения в записях являются несуществующими (поскольку файлы записей являются входами в TLC; другие типы файлов, такие как исходный код C, являются выходными), но могут быть полезными.

Кроме того, можно использовать несколько директив TLC. %assign для изменения записей:

%createrecordСоздает новые записи верхнего уровня, а также может указывать вложенные записи в них, включая пары имя/значение.
%addtorecordДобавляет поля к существующей записи. Новыми полями могут быть пары имя/значение или псевдонимы к существующим записям.
%mergerecordОбъединяет одну или несколько записей. Первая запись содержит себя плюс копии содержимого других записей, указанных командой, в последовательности.
%copyrecordСоздает новую запись как %createrecord за исключением компонентов записи, полученных из указанной существующей записи.
%undef varУдаляет (удаляет) var (переменная или запись) из области. Если var является полем в записи, TLC удаляет поле из записи. Если var является массивом записи (списком), TLC удаляет первый элемент массива; остальные элементы остаются доступными. Можно удалить только записи, созданные с помощью %createrecord или %copyrecord.

Дополнительные сведения об этих директивах см. в разделе Директивы компилятора целевого языка.

Списки индексов

Файлы записей могут содержать списки или последовательности записей, имеющих один и тот же идентификатор. Наш пример содержит список из трех записей, определенных как Project в пределах Top сфера применения. Ссылки на списки индексируются, пронумеруются от 0, в том порядке, в котором они отображаются в файле записи. Вот код TLC, который компилирует данные из Name области Project список:

* Index lists of values, e.g.
%assign projects = Top.Project[0].Name + ", " + Top.Project[1].Name...
+ ", " + Top.Project[2].Name
  "%assign projects = Top.Project[0].Name + ", " + Top.Project[1].Name..."
  "+ ", " + Top.Project[2].Name"
  projects expands to Top.Project[0].Name + ", " + Top.Project[1].Name
  + ", " + Top.Project[2].Name = %<projects>

Scope.Record[n].Field синтаксис аналогичен синтаксису, используемому в C для ссылки на элементы в массиве структур.

Хотя явное индексирование, такое как выше, вполне приемлемо, часто предпочтительно использовать конструкцию цикла при прохождении целых списков, как показано в разделе «Списки цикла».

Списки закольцовывания

По соглашению, разделу файла записи, который занимает список, предшествует запись, указывающая, сколько элементов списка присутствует. В model.rtw файлы, такие параметры объявляются как NumIdent, где Ident - идентификатор, используемый для записей в следующем списке. В guide.rtw, Project список выглядит следующим образом:

  NumProject    3                   # Indicates length of following list
  Project {                         # First list item, called Top.Project[0]
    Name       "Tea"                #   Alpha field Name, Top.Project[0].Name
    Difficulty  3                   #   Numeric field Top.Project[0].Difficulty
  }                                 # End of first list item
  Project {                         # Second list item, called Top.Project[1]
    Name       "Gillian"            #   Alpha field Name, Top.Project[1].Name
    Difficulty  8                   #   Numeric field Top.Project[1].Difficulty
  }                                 # End of second list item
  Project {                         # Third list item, called Top.Project[2]
    Name       "Zaphod"             #   Alpha field Name, Top.Project[2].Name
    Difficulty  10                  #   Numeric field Top.Project[2].Difficulty
  }                                 # End of third list item

Таким образом, значение NumProject описывает, сколько Project возникают записи.

Примечание

model.rtw файлы также могут содержать записи, начинающиеся с Num но не являются параметрами размера списка. TLC не требует, чтобы параметры размера списка начинались с Num. Поэтому при толковании нужно быть осторожным NumIdent идентификаторы записей. Встроенная функция TLC SIZE() может определить количество записей в указанной области, следовательно, длину списка.

Последний сегмент read-guide.tlc использует %foreach контур, управляемый NumProject , для итерации Project перечислять и манипулировать его значениями.

* Traverse and manipulate list data via loops, e.g.
%assign diffSum = 0.0
%foreach i = Top.NumProject
  - At top of Loop, Project = %<Top.Project[i].Name>; Difficulty =...
 %<Top.Project[i].Difficulty>
  %assign diffSum = diffSum + Top.Project[i].Difficulty
  - Bottom of Loop, i = %<i>; diffSum = %<diffSum>
%endforeach
%assign avgDiff = diffSum / Top.NumProject
  Average Project Difficulty expands to diffSum / Top.NumProject = %<diffSum> ...
 / %<Top.NumProject> = %<avgDiff>

Как вы помните, выходные данные TLC выглядят следующим образом:

* Traverse and manipulate list data via loops, e.g.
- At top of Loop, Project = Tea; Difficulty = 3
  - Bottom of Loop, i = 0; diffSum = 3.0
  - At top of Loop, Project = Gillian; Difficulty = 8
  - Bottom of Loop, i = 1; diffSum = 11.0
  - At top of Loop, Project = Zaphod; Difficulty = 10
  - Bottom of Loop, i = 2; diffSum = 21.0
Average Project Difficulty expands to diffSum / Top.NumProjects = 21.0 / 3 = 7.0
После инициализации переменной суммирования diffSum, a %foreach вводится цикл с переменной i объявлен как счетчик цикла, итерация до NumProject. Область цикла - это все операторы, встречающиеся до соответствующего %endforeach достигается (%foreach петли могут быть вложенными).

Примечание

Итерации цикла неявно начинаются с нуля и имеют значение, меньшее индекса, указывающего верхнюю границу. Индекс цикла является локальным по отношению к телу цикла.

Изменить read-guide.tlc

Теперь, когда вы изучили read-guide.tlc, пришло время изменить его. В этом упражнении представлены два важных средства TLC, управление файлами и управление объемом. Вы реализуете оба в read-guide.tlc сценарий.

Основы управления файлами

Сценарии TLC почти неизменно выдают выходные данные в виде потоков символов. Выходные данные обычно направляются в один или несколько буферов и файлов, совместно называемых потоками. На данный момент вы направили вывод из read-guide.tlc в командное окно MATLAB, так как вы включили -v включите командную строку. Доказать это, пропустив -v при выполнении read-guide.tlc. Напечатать

tlc -r guide.rtw read-guide.tlc

Похоже, ничего не происходит. Фактически сценарий выполнялся, но вывод направлялся на нулевое устройство (иногда называемое «битовым ведром»).

Существует один активный выходной файл, даже если он имеет значение null. Чтобы указать, открыть и закрыть файлы, используйте следующие директивы TLC:

%openfile streamid ="filename" , "mode"
%closefile streamid
%selectfile streamid

Если имя файла не задано, последующие выходные данные поступают в буфер памяти с именем streamid. Если режим не задан, TLC открывает файл для записи и удаляет все существующее содержимое (в соответствии с механизмами защиты файлов системного уровня). Допустимые идентификаторы режима: a (добавить) и w (запись, значение по умолчанию). Заключите эти символы в кавычки.

%openfile директива создает файл/буфер (в w режим) или открывает существующий (в a режим). Обратите внимание на требуемый знак равенства для спецификации файла. Несколько потоков могут быть открыты для записи, но только один может быть активным одновременно. Для переключения выходных потоков используйте %selectfile директива. Вам не нужно закрывать файлы, пока вы не закончите с ними.

Выходной поток по умолчанию, который можно сопоставить с идентификатором потока. NULL_FILEявляется null. Другим встроенным потоком является STDOUT. При активации с помощью %selectfile, STDOUT направляет выходные данные в окно команд MATLAB.

Примечание

Потоки NULL_FILE и STDOUT всегда открыты. Задание их с помощью %openfile генерирует ошибки. Использовать %selectfile для их активации.

Директива %closefile закрывает текущий выходной файл или буфер. До %openfile или %selectfile встречается директива, вывод переходит к ранее открытому потоку (или, если нет, к null). Использовать %selectfile для обозначения открытого потока для чтения или записи. На практике многие сценарии TLC записывают части выходных данных в отдельные буферы, которые затем выбираются в последовательности, и их содержимое перестраивается в один или несколько файлов.

Реализация управления выходными файлами

В вашем tlctutorial/guide папка, найдите файл read-guide-file-src.tlc. Предоставленная версия этого файла содержит комментарии и три строки добавленного текста. Отредактируйте этот файл для реализации управления выходными файлами следующим образом:

  1. Открытый read-guide-file-src.tlc в текстовом редакторе.

  2. Сохранить файл как read-guide-file.tlc.

  3. Обратите внимание на пять строк комментария, начинающихся с %% ->.

    В каждом из этих замечаний включить директиву TLC, как указано.

  4. Сохранить отредактированный файл как read-guide-file.tlc.

  5. Выполнить read-guide-file.tlc с помощью следующей команды:

    tlc -r guide.rtw read-guide-file.tlc

    В случае успеха TLC создает файл guidetext.txt который содержит ожидаемые выходные данные, и отображается окно команды MATLAB

    *** Output being directed to file: guidetext.txt
    *** We're almost done . . .
    *** Processing completed.

Если эти сообщения не были обнаружены или не был создан текстовый файл, просмотрите материал и повторите попытку. Если проблемы сохраняются, проверьте read-guide-file.tlc в guide/solutions , чтобы узнать, как следует указывать управление файлами.

Основные сведения об объеме

Структура файлов записей объясняет иерархическую организацию записей. Каждая запись существует в области, определенной записями, в которые она вложена. Файл примера, guide.rtw, содержит следующие области:

Top
Top.Employee
Top.Project[0]
Top.Project[1]
Top.Project[2]

Для ссылки на поле или запись укажите ее область, даже если не существует другого контекста, содержащего идентификатор. Например, в guide.rtw, поле FirstName существует только в области Top.Employee. Вы должны ссылаться на него как Top.Employee.FirstName при каждом обращении к нему.

Когда модели имеют области, которые глубоко вложены, это может привести к очень длинным идентификаторам, которые утомительны и ошибки склонны к типу. Например:

CompiledModel.BlockOutputs.BlockOutput.ReusedBlockOutput

Этот идентификатор имеет длинную область и имеет похожие имена элементов, которые можно ввести неправильно.

%with/%endwith директива облегчает бремя кодирования сценариев TLC и уточняет их поток управления. Синтаксис:

%with RecordName
  [TLC statements]
%endwith

Каждый %with в конечном итоге за ним следует %endwith, и эти пары могут быть вложенными (но не перекрывающимися). Если RecordName находится ниже верхнего уровня, нет необходимости включать область верхнего уровня в его описание. Например, чтобы сделать текущий объем guide.rtw Top.Employee, можно указать

%with Employee
  [TLC statements]
%endwith

Естественно, %with Top.Employee также является допустимым синтаксисом. Один раз заключенный в скобки %with/%endwith, идентификаторы записей в инструкциях TLC не требуют указания их внешней области. Однако обратите внимание на следующие условия:

  • Доступ к записям можно получить за пределами текущего %with область, но их необходимо квалифицировать полностью (например, используя имя записи и поля).

  • Каждый раз, когда выполняется назначение записям внутри %with директива, вы должны квалифицировать их полностью.

Изменить область с помощью %with

В последнем сегменте этого упражнения сценарий TLC изменяется путем добавления %with/%endwith директива. Также необходимо изменить имена идентификаторов записей (но не имен локальных переменных), чтобы учесть изменения области в результате %with директивы.

  1. Открытие сценария TLC read-guide-scope-src.tlc в текстовом редакторе.

  2. Сохранить файл как read-guide-scope.tlc.

  3. Обратите внимание на строки комментариев, которые начинаются с %% ->.

    Под каждым из этих комментариев вставить директиву TLC или изменить уже имеющиеся инструкции, как указано.

  4. Сохранить отредактированный файл как read-guide-scope.tlc.

  5. Выполнить read-guide-scope.tlc с помощью следующей команды:

    tlc -v -r guide.rtw read-guide-scope.tlc

Выходной сигнал должен быть точно таким же, как у read-guide.tlc, за исключением, возможно, пробела, который вы могли ввести, отступив разделы кода внутри %with/%endwith или путем исключения пустых строк.

Полное определение области внутри %with контекст не является ошибкой, он просто не нужен. Однако не удалось полностью указать его область при назначении записи (например, %assign GrossRate = wageCost) является недопустимым.

Если в результате выполнения сценария возникают ошибки, просмотрите приведенное выше обсуждение области и отредактируйте read-guide-scope.tlc для их устранения. В крайнем случае осмотрите read-guide-scope.tlc в /solutions чтобы узнать, как в этом упражнении следует обрабатывать область.

Дополнительные сведения см. в разделах Области в файле model.rtw и Область действия переменных.

Передать и использовать параметр

Для передачи параметров из командной строки в исполняемый файл TLC можно использовать команды TLC и встроенные функции. Наиболее общим командным переключателем является -a, которая назначает произвольные переменные. Например:

tlc -r input.rtw -avar=1 -afoo="abc" vars.tlc

Результат передачи этой пары строк через -a аналогично объявлению и инициализации локальных переменных в исполняемом файле (здесь vars.tlc). Например:

%assign var = 1
%assign foo = "abc"

Объявлять такие переменные в файле TLC не требуется, и они доступны для использования при установке с -a. Однако ошибки возникают, если код назначает необъявленные переменные, которые не указаны с помощью -a переключаться при вызове файла. Также обратите внимание, что (в отличие от -r switch) пробел не должен разделяться -a от объявляемого параметра.

В последнем разделе этого учебного пособия используется встроенная функция. GET_COMMAND_SWITCH() печать имени файла записи, используемого в сценарии TLC, и предоставление параметра для управления подавлением кода. По умолчанию код выполняется, но подавляется, если командная строка содержит -alist=0:

  1. Открытие сценария TLC read-guide-param-src.tlc в текстовом редакторе.

  2. Сохранить файл как read-guide-param.tlc.

  3. Чтобы разрешить программе доступ к входному имени файла из командной строки, выполните следующие действия.

    1. Ниже строки %selectfile STDOUT, добавьте строку:

      %assign inputfile = GET_COMMAND_SWITCH ("r")

      %assign объявляет и задает переменные. В этом случае он содержит идентификатор строкового имени файла. GET_COMMAND_SWITCH() возвращает любой строковый аргумент, следующий за указанным параметром команды TLC. Для имен встроенных функций необходимо использовать UPPERCASE.

    2. Изменить строку "*** WORKING WITH RECORDFILE"следующим образом:

      *** WORKING WITH RECORDFILE %<inputfile>
  4. Для управления выполнением раздела кода TLC выполните следующие действия:

    1. Ниже строки "%assign inputfile = GET_COMMAND_SWITCH ("r")", добавить:

      %if (!EXISTS(list))
      	%assign list = 1
      %endif
      Программа проверяет, был ли объявлен параметр списка с помощью встроенной функции. EXISTS(). Если переменная списка не существует, программа назначает ее. Это определяет list и по умолчанию его значение равно TRUE.

    2. Заключить строки кода в %if блок.

      %if (list)
          * Assign contents of a field to a variable, e.g.
            %assign worker = FirstName
            "%assign worker = FirstName"
            worker expands to FirstName = %<worker>
      %endif

      Теперь присвоенный код worker отправляется на выход только тогда, когда list является TRUE.

    3. Сохранить read-guide-param.tlc.

  5. Выполнить read-guide-param.tlc и проверьте выходные данные с помощью команды

    tlc -r guide.rtw read-guide-param.tlc

    Это дает

    *** WORKING WITH RECORDFILE [guide.rtw]
    * Assign contents of a field to a variable, e.g.
          "%assign worker = FirstName"
          worker expands to FirstName = Arthur
    ***END
  6. Выполнитьread-guide-param.tlc с помощью команды:

    tlc -r guide.rtw -alist=0 read-guide-param.tlc

    С помощью -alist=0 , на выходе отображается только информация за пределами if заявление.

    *** WORKING WITH RECORDFILE [guide.rtw]
    ***END

Обзор

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

%addincludepathВключить TLC для поиска включенных файлов.
%addtorecordДобавление полей в существующую запись. Новыми полями могут быть пары имя/значение или псевдонимы к существующим записям.
%assignСоздание или изменение переменных.
%copyrecordСоздайте новую запись и, если применимо, укажите вложенные записи в ней, включая пары имя/значение. Компоненты записи получены из указанной существующей записи.
%createrecordСоздайте новые записи верхнего уровня и, если применимо, укажите вложенные записи в них, включая пары имя/значение.
%foreach/%endforeachИтерация переменной цикла от 0 до верхнего предела.
%if/%endifУправление выполнением кода, как в C.
%includeВставьте один файл в другой, как в C.
%mergerecordОбъединение одной или нескольких записей. Первая запись содержит себя плюс копии содержимого других записей, указанных командой, в последовательности.
%selectfileПрямые выходы в поток или файл.
%undef varУдалить (удалить) var (переменная или запись) из области. Если var является полем в записи, TLC удаляет поле из записи. Если var является массивом записи (списком), TLC удаляет первый элемент массива; остальные элементы остаются доступными. Только записи, созданные с помощью %createrecord или %copyrecord может быть удален.
%with/%endwithДобавление области для упрощения ссылок на блоки.

Связанные темы