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

Обзор руководства

Objective: Осмыслите структуру файлов записей и узнайте, как их разобрать с директивами TLC.

<reservedrangesplaceholder1> <reservedrangesplaceholder0>/ toolbox/rtw/rtwdemos/tlctutorial/guide (открыто)

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

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

  1. Structure of Record Files - некоторый фон и простой пример

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

  3. Anatomy of a TLC Script - деконструкция презентации

  4. <reservedrangesplaceholder1> <reservedrangesplaceholder0> - Экспериментируйте с TLC

  5. Pass and Use a Parameter - Передайте параметры из командной строки в файлы TLC

  6. Review

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

Генератор кода компилирует модели в структурированную форму, называемую файлом записи, называемым 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

Обратите внимание на использование команды:

  • The -r switch (for read) определяет файл входных данных, в этом случае guide.rtw.

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

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

Анатомия скрипта TLC

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

Конвенции о кодировании

Это некоторые основные синтаксисы 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
    Необязательный префикс двойного двоеточия указывает, что назначенная переменная является глобальной переменной. В его отсутствии TLC создает или изменяет локальную переменную в текущих возможностях.

  • Линия 4 - Отображения

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

  • Линия 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>"
    Альтернативный метод использует evals полей и одинаково эффективен.

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.rtw файлы, такие параметры объявлены как Num 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 Ident идентификаторы записей. Встроенная функция 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, а %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. Предоставленная версия этого файла содержит комментарии и три добавленные линии текста. Отредактируйте этот файл для реализации управления выходным файлом следующим образом:

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

  2. Сохраните файл следующим read-guide-file.tlc.

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

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

  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

Этот идентификатор имеет область возможностей, которая длинна и имеет аналогичные имена элементов, которые вы можете легко ввести неправильно.

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 директивы.

  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 switch при вызове файла. Также обратите внимание, что (в отличие от -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")

      The %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 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Добавьте возможности, чтобы упростить ссылки на блоки.

Похожие темы