Objective: Осмыслите структуру файлов записей и узнайте, как их разобрать с директивами TLC.
<reservedrangesplaceholder1> <reservedrangesplaceholder0>
(открыто)/ toolbox/rtw/rtwdemos/tlctutorial/guide
В этом руководстве вы интерпретируете простой файл структурированных записей с серией TLC скриптов. Вы узнаете, как структурированы записи и как %assign TLC
и %<>
token expansion их обработки используются директивы. В сложение руководства иллюстрирует циклы, использующие %foreach
, и исследования с использованием %with
.
В руководство включены следующие шаги, которым вы должны следовать последовательно:
Structure of Record Files - некоторый фон и простой пример
Interpret Records - Представление содержимого файла записи
Anatomy of a TLC Script - деконструкция презентации
<reservedrangesplaceholder1> <reservedrangesplaceholder0>
- Экспериментируйте с TLC
Pass and Use a Parameter - Передайте параметры из командной строки в файлы TLC
Review
Генератор кода компилирует модели в структурированную форму, называемую файлом записи, называемым
. Такие скомпилированные файлы модели аналогичны по синтаксису и организации исходным файлам модели, тем, что они содержат серию иерархически вложенных записей формыmodel
.rtw
recordName {itemName itemValue}
Имена элементов алфавитные. Значениями элементов могут быть строки или числа. Числовыми значениями могут быть скаляры, векторы или матрицы. Фигурные скобки устанавливают содержимое каждой записи, которая может содержать один или несколько элементов, разделенных пространством, вкладкой или возвращаемыми символами.
В
файл, имя записи верхнего уровня (первой) model
.rtwCompiledModel
. Каждый блок представлен подзаписи в нем, идентифицируемой именем блока. 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
. Сделайте это самостоятельно сейчас, выполнив следующие шаги:
В MATLAB измените папку (cd
) на вашу копию tlctutorial/guide
в рабочей папке.
Чтобы получить только что перечисленный выход, обработайте guide.rtw
с помощью скрипта TLC read-guide.tlc
путем ввода следующей команды:
tlc -v -r guide.rtw read-guide.tlc
Обратите внимание на использование команды:
The -r
switch (for read) определяет файл входных данных, в этом случае guide.rtw
.
TLC скрипт, обрабатывающий файл данных, задается последним набранной лексемой.
The -v
switch (for verbose) направляет выходу в командное окно, если TLC- файла не обрабатывает это само.
Теперь ты рассекаешь скрипт, который только что пробежал. Каждый «абзац» выхода guide.tlc
обсуждается последовательно в следующих кратких разделах:
Соглашения о кодировании - Прежде чем вы начнете
Заголовок файла - Информация о заголовке и директива форматирования
Расширение токена - Оценка идентификаторов полей и переменных
Общее назначение - Использование %assign
директива
String Processing Plus - Методы сборки строк
Арифметические операции - расчеты на полях и переменных
Изменение записей - Изменение, копирование, добавление к записям
Списки индексов - Ссылки на элементы списка с нижними индексами
Списки циклов - Сведения о конструкции и поведении циклов
Это некоторые основные синтаксисы TLC и конвенции о кодировании:
%% Comment
| Комментарий TLC, который не выводится |
/* comment */
| Комментарий, будет выведен |
%keyword
| Директива TLC (ключевое слово), начните с "% ” |
%<expr> | Лексема TLC |
. (период) | Оператор Scoping, например Top.Lev2.Lev3 |
... (в конце линии) | Продолжение оператора (линия пропуска не выводится) |
\ (в конце линии) | Продолжение оператора (вывод пропуска линии) |
localvarIdentifier
| Локальные переменные начинаются в нижнем регистре |
GlobalvarIdentifier
| Глобальные переменные начинаются в верхнем регистре |
RecordIdentifier
| Идентификаторы записей начинаются в верхнем регистре |
EXISTS()
| Встроенные функции TLC названы в верхнем регистре Note: 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>
к нему. The %assign
директива создает новые и изменяет существующие переменные. Его общий синтаксис:
%assign ::variable = expression
Линия 4 - Отображения
%<Top.Date> -- evaluates to:
%<Top.Date>
не расширяя его. Строка создается путем вставки двух литералов.%assign td = "%" + "<Top.Date>"
Линия 5 - Оценивает (расширяет) запись Top.Date
. Точнее, он оценивает поле Date
который существует в области видимости Top
. Синтаксис %<expr>
вызывает экспрессию expr
(который может быть записью, переменной или функцией), подлежащей оценке. Эта операция иногда упоминается как eval.
Примечание
Вы не можете вложить %<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>"
The +
оператор, который является ассоциативным, также работает для числовых типов, векторов, матриц и записей:
Числовые типы - Добавить два выражения вместе; оба операнда должны быть числовыми. Для примера:
* Numeric Type example, e.g. Top.Employee.PayRate = %<Top.Employee.PayRate> Top.Employee.Overhead = %<Top.Employee.Overhead> %assign td = Top.Employee.PayRate + Top.Employee.GrossRate td = Top.Employee.PayRate + Top.Employee.Overhead td evaluates to %<td>
* 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. %assign v1 = [0, 1, 2, 3] v1 is %<v1> %assign tp1d = Top.Project[1].Difficulty Top.Project[1].Difficulty is %<tp1d> %assign v2 = v1 + tp1d v2 = v1 + Top.Project[1].Difficulty v2 evaluates to: %<v2>
* 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. %assign mx1 = [[4, 5, 6, 7]; [8, 9, 10, 11]] mx1 is %<mx1> v1 is %<v1> %assign mx = mx1 + v1 mx = mx1 + v1 mx evaluates to %<mx>
* 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. %assign StartDate = "August 28, 2008" StartDate is %<StartDate> %assign tsd = Top + StartDate Top + StartDate Top.StartDate evaluates to %<Top.StartDate>
* 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 does, кроме компонентов записи, полученных из указанной вами существующей записи. |
%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>
The Scope.Record[n].Field
синтаксис аналогичен синтаксису, используемому в C для ссылки на элементы в массиве структур.
Хотя явное индексирование, такое как выше, совершенно приемлемо, часто предпочтительно использовать конструкцию цикла при прохождении по целым спискам, как показано в Циклических списках.
Согласно соглашению, разделу файла записи, который занимает список, предшествует запись, которая указывает, сколько элементов списка присутствует. В
файлы, такие параметры объявлены как model
.rtwNum
, где Ident
- идентификатор, используемый для записей в следующем списке. В 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
. Поэтому необходимо быть осторожным при интерпретации Num
идентификаторы записей. Встроенная функция TLC Ident
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
, а %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
(напишите, значение по умолчанию). Заключайте эти символы в кавычки.
The %openfile
директива создает файл/буфер (в w
mode), или открывает существующее (в 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
. Предоставленная версия этого файла содержит комментарии и три добавленные линии текста. Отредактируйте этот файл для реализации управления выходным файлом следующим образом:
Откройте read-guide-file-src.tlc
в текстовом редакторе.
Сохраните файл следующим read-guide-file.tlc
.
Обратите внимание на пять строки с комментариями, которые начинаются с %% ->
.
В каждом из этих замечаний включить указанную директиву ТСО.
Сохраните отредактированный файл следующим read-guide-file.tlc
.
Выполните 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
Этот идентификатор имеет область возможностей, которая длинна и имеет аналогичные имена элементов, которые вы можете легко ввести неправильно.
The %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
директивы.
Откройте скрипт TLC read-guide-scope-src.tlc
в текстовом редакторе.
Сохраните файл следующим read-guide-scope.tlc
.
Обратите внимание на строки с комментариями, которые начинаются с %% ->
.
В каждом из этих замечаний вставьте директиву TLC или измените уже существующие операторы, как указано.
Сохраните отредактированный файл следующим read-guide-scope.tlc
.
Выполните 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
switch при вызове файла. Также обратите внимание, что (в отличие от -r
switch) пространство не должен разделяться -a
от параметра, который вы объявляете.
В заключительном разделе этого руководства вы используете встроенную функцию GET_COMMAND_SWITCH()
чтобы распечатать имя файла записи, используемого в скрипте TLC, и предоставить параметр, чтобы контролировать, подавлен ли код. По умолчанию код выполняется, но подавляется, если командная строка содержит -alist=0
:
Откройте скрипт TLC read-guide-param-src.tlc
в текстовом редакторе.
Сохраните файл следующим read-guide-param.tlc
.
Чтобы включить доступ к входу файла из командной строки, выполните следующие действия:
Под линией %selectfile STDOUT
, добавить линию:
%assign inputfile = GET_COMMAND_SWITCH ("r")
The %assign
директива объявляет и устанавливает переменные. В этом случае он содержит строковый идентификатор имени файла. GET_COMMAND_SWITCH()
возвращает любой строковый аргумент после заданного командного ключа TLC. Необходимо использовать UPPERCASE для встроенных имен функций.
Измените линию "*** WORKING WITH RECORDFILE
"читать следующим образом:
*** WORKING WITH RECORDFILE %<inputfile>
Чтобы контролировать выполнение раздела кода TLC, выполните следующее:
Под линией "%assign inputfile = GET_COMMAND_SWITCH ("r")
, "добавить:
%if (!EXISTS(list)) %assign list = 1 %endif
EXISTS()
. Если переменная списка не существует, программа присваивает ее. Это определяет list
и по умолчанию его значение TRUE
.Строки кода заключаются в %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
.
Сохраните read-guide-param.tlc
.
Выполните 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
Выполните read-guide-param.tlc
с помощью команды:
tlc -r guide.rtw -alist=0 read-guide-param.tlc
С -alist=0
switch, выходные выходы отображают только информацию за пределами 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 | Добавьте возможности, чтобы упростить ссылки на блоки. |