Цель: Понять структуру файлов записей и научиться анализировать их с помощью директив TLC.
Папка: (открыто)matlabroot/toolbox/rtw/rtwdemos/tlctutorial/guide
В этом учебном пособии рассматривается простой файл структурированных записей с серией сценариев TLC. Вы узнаете, как структурированы записи и как TLC %assign и %<>
для их обработки используются директивы расширения маркеров. Кроме того, в учебном пособии показаны циклы с использованием %foreachи определение области с использованием %with.
Учебное пособие включает следующие шаги, которым необходимо следовать последовательно:
Структура файлов записей - некоторые фоновые и простые примеры
Интерпретировать записи - представление содержимого файла записи
Анатомия сценария TLC - деконструкция презентации
Изменить
read-guide.tlc - Эксперимент с ТСХ
Передать и использовать параметр - передать параметры из командной строки в файлы TLC
Обзор
Генератор кода компилирует модели в структурированную форму, называемую файлом записи, называемую . Такие скомпилированные файлы модели аналогичны по синтаксису и организации файлам исходных моделей, поскольку содержат ряд иерархически вложенных записей формы.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
Использование команды Note:
-r коммутатор (для чтения) идентифицирует файл входных данных, в данном случае guide.rtw.
Сценарий TLC, обрабатывающий файл данных, определяется последним введенным маркером.
-v switch (для подробных данных) направляет выходные данные в окно команд, если только TLC-файл не обрабатывает их сам.
Теперь вы рассекаете сценарий, который только что запустили. Каждый «параграф» выходных данных guide.tlc рассматривается последовательно в следующих кратких разделах:
Соглашения по кодированию - перед началом работы
Заголовок файла - информация о заголовке и директива по форматированию
Расширение маркера - оценка идентификаторов полей и переменных
Общее присвоение - использование %assign директива
String Processing Plus - Методы сборки строк
Арифметические операции - вычисления для полей и переменных
Изменение записей - изменение, копирование, добавление к записям
Индексные списки - ссылки на элементы списка с подстрочными индексами
Списки циклов - подробные сведения о построении и поведении циклов
Ниже приведены некоторые основные положения о синтаксисе и кодировании 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
Строка 4 - Отображение
%<Top.Date> -- evaluates to:
%<Top.Date> не расширяя его. Он создает строку, вставляя два литерала.%assign td = "%" + "<Top.Date>"
Строка 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.rtwNum, где Ident - идентификатор, используемый для записей в следующем списке. В Identguide.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 IdentSIZE() может определить количество записей в указанной области, следовательно, длину списка.
Последний сегмент 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. Предоставленная версия этого файла содержит комментарии и три строки добавленного текста. Отредактируйте этот файл для реализации управления выходными файлами следующим образом:
Открытый read-guide-file-src.tlc в текстовом редакторе.
Сохранить файл как read-guide-file.tlc.
Обратите внимание на пять строк комментария, начинающихся с %% ->.
В каждом из этих замечаний включить директиву 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
Этот идентификатор имеет длинную область и имеет похожие имена элементов, которые можно ввести неправильно.
%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 переключаться при вызове файла. Также обратите внимание, что (в отличие от -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") %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 , на выходе отображается только информация за пределами 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 | Добавление области для упрощения ссылок на блоки. |