<< Click to Display Table of Contents >> Navigation: Для опытных пользователей > Стандартные фрагменты > Метод стандартных фрагментов > Операторы |
В логические фрагменты табличного типа включены следующие операторы:
:В (ВВОД) - оператор ввода значений переменных параметров;
:Х (АРИФМЕТИКА) - оператор вычисления арифметических выражений;
:П (ПЕРЕХОД) - оператор безусловного перехода;
:Е (ЕСЛИ) - оператор условного перехода;
:Н (НАЗНАЧЕНИЕ) - проверка назначений переменных;
:Ф (ВЫЗОВ ФУНКЦИИ) – вызов функции или вложенного фрагмента;
:М (МЕТКА) - метка перехода;
:Ц (ЦИКЛ) - оператор цикла и конец цикла;
:Т (ТАБЛИЦА) - оператор - логическая таблица;
:Б (БЛОК) - оператор блокирования строк;
:К (КОММЕНТАРИЙ) - комментарий в тексте фрагмента;
:О (ОШИБКА) - оператор информации об ошибке.
Операторы табличных СФ в общем виде имеют следующую структуру:
<метка оператора><тело оператора>*
например:
:ХА=(100+?ЦЕНА.):1,5*
Любая строка или оператор СФ могут быть помечены с помощью метки перехода, которая в общем случае записывается так:
:М<целое,6>
Метка может выступать и как самостоятельная строка-оператор, например:
:М25*
Если метка ставится перед строкой или оператором, то после метки ставится символ "'". Перед строкой или оператором можно ставить несколько меток, например:
:М1':М25':К КОНЕЦ СФ*
|
Оператор ввода значений переменных
Оператор ввода значений переменных (ВВОД) позволяет ввести (в смысле присваивания) значения различным переменным параметрам по следующему общему правилу:
<ВВОД>::=:В<список ввода>*
где: <список ввода>::=<ввод переменной> ['<ввод переменной.] ... <ввод переменной>::=<имя переменной>=<специальный текст>['=<специальный текст>] ...
Специальный текст - это обычная последовательность символов без использования "'" и "*", в котором могут записываться идентификаторы переменных параметров с выделением их с двух сторон символами "?" и ".", например: :ВК=БЕТОН МАРКИ ?МАРКА.*
Переменная в операторе ВВОД может получить одно или несколько значений, например:
:ВРАСХОД=12'=18'=БОЛЬШЕ 18*
Переменная может переопределяться оператором ввод любое количество раз с учетом общих ограничений на переменные (см. ниже), например:
:ВВАРИАНТ=1* ... (другие операторы) :ВВАРИАНТ=2*
Если в специальном тексте встретится идентификатор переменной, ранее нигде не определенной, то такой переменной будет присвоено значение "?". Примеры: :ВА=З'В=ПЕСОК'=БЕТОН'=ЩЕБЕНЬ* :ВТ1=25-17* :ВС=Е?Т1.* :ВД=Е?Т2.*
В этих примерах переменный параметр А получит значение З; переменный параметр В получит три последовательных значения (ПЕСОК, БЕТОН и ЩЕБЕНЬ) и будет представлять одномерный массив с тремя элементами; переменная Т1 получит значение 25-17; с учетом этого переменная С получит значение Е25-17; что же касается переменной Д, то если Т2 нигде раньше не встречалось во фрагменте или обращении к нему, - получит значение ?.
Оператор ВВОД имеет еще одну важную особенность, которая позволяет вводимые переменные определять как “глобальные”. В этом случае синтаксис записи оператора ВВОД имеет следующий вид:
<ВВОД>::=:В<список ввода>*
где: <список ввода>::=<ввод переменной> ['<ввод переменной.] ... <ввод переменной>::=$<имя переменной>=<специальный текст>['=<специальный текст>] ...
Символ “$” перед именем переменной означает, что переменная будет объявлена, как глобальная. Глобальные переменные со своими значениями будут переданы в любой следующий вызванный фрагмент, находящийся в тех же исходных данных. Такой подход позволяет необходимые расчеты в одном фрагменте или нескольких фрагментах, передать следующим фрагментам для дальнейшей обработки. Объявлять переменные, как глобальные можно в начале или в конце фрагмента. Дальнейшее новое присвоение этим переменным значений, как в операторах ВВОД, АРИФМЕТИКА или диалогового ввода данных оставляет их всегда глобальными, если они были введены как глобальные. Пример: объявление переменных, как глобальных в начале фрагмента;
:В$ОБЪЕМ=’$МАРКА=’$УСЛОВИЯ=*
В этом случае все эти переменные, если далее во фрагменте примут какие либо новые значения, то при выходе из фрагмента эти новые значения сохраняются и передаются следующему фрагменту.
Пример: объявление переменных, как глобальных в конце фрагмента;
:В$ОБЪЕМ=?ОБЪЕМ.’$МАРКА=?МАРКА.’$УСЛОВИЯ=?УСЛОВИЯ.*
В этом случае можно было работать с фрагментом без объявления глобальных переменных, а только в конце их объявить и присвоить им свои же значения.
Дополнительно при помощи признаков “+” или “-” можно назначить в операторе ВВОД для вводимых переменных свойства возвращения переменных в обращение к СФ. А также убрать свойства возвращения переменных если такое свойство имела переменная. Пример: … :В+Вес_изделия=100кг’+Тип=10’Количество=5* …
Такая строка фрагмента позволяет вывести в обращение к СФ переменные и их текущие значения, если они не были определены в обращении ранее.
?1-1-2’…’Вес_изделия=100’Тип=10’…*
Запись :В-Тип=10* снимает свойство возвращения переменной в обращение к СФ.
|
Оператор вычисления значений переменных
Оператор вычисления значений переменных (АРИФМЕТИКА) позволяет на стадии трансляции стандартных фрагментов производить арифметические действия над переменными параметрами и присваивать им новые вычисленные значения:
<АРИФМЕТИКА>::=:Х[<целое,2>]<список арифметических выражений>* <список арифметических выражений>::=<вычисление переменной> ['<вычисление переменной>] ... <вычисление переменной>::=<имя переменной>= <арифметическое выражение> ['=<арифметическое выражение>] ...
Арифметическое выражение здесь понимается в обычном смысле: его операндами могут быть любые числа без знака в виде целых чисел или чисел с запятой, идентификаторы переменных, выделенные с двух сторон символами "?" и ".", а также следующие операции:
Порядок выполнения действий определяется старшинством операций: вначале выполняются С, М и Ц, затем . и : и последними + и -; а также же с помощью круглых скобок ( ) при произвольной глубине их вложения. Результат вычисления арифметического выражения округляется до десяти знаков после запятой (по умолчанию). Общая запись оператора расширена возможностью вычисления результата с заданной точностью. :Х[(<целое>)]<имя переменной>=<арифметическое выражение>… где <целое> число от 0 до 18. При явном задании числа в круглых скобках переменная вычисляется и округляется. Округление происходит с тем количеством знаков после запятой, которое указано в скобках. Если явно не задавать параметр <целое>, то результат округляется до десяти знаков после запятой. Использование точности 0 предназначено для целочисленного результата. Например, следующие две записи имеют одинаковый результат для положительных чисел.
:ХИТОГ=Ц((?ПОЗ.Х?КОЭФ.+?ДОП.)+0,5)* :Х(0)ИТОГ=?ПОЗ.Х?КОЭФ.+?ДОП.*
Переменная ИТОГ будет иметь целочисленный округленный результат. Максимальное количество знаков после запятой ограничено цифрой 18, большее задание этого значения приведет к сообщению об ошибке. :X(5)ИТОГ= … правильное задание параметра. :X(20)ИТОГ= … неправильное задание параметра. Переменная в операторе АРИФМЕТИКА может принимать одно или несколько значений. Переменные можно перевычислять в других операторах АРИФМЕТИКА произвольное число раз. Значениями идентификаторов переменных в правой части арифметических выражений могут быть только числа, арифметические выражения или специальный знак "?", указывающий на отсутствие значений у переменных. Пример:
:ВОБЪЕМ=(12,4+33,5+15,8)Х5* :ХИТОГ=22,32+?ОБЪЕМ.* Замечание: переменная ОБЪЕМ содержит в себе запись арифметического выражения, как текстовая информация. Переменная ОБЪЕМ может быть введена и при помощи диалоговых операторов ввода информации, как текстовая информация.
Если в арифметическом выражении встретится отсутствующая по умолчанию переменная, или переменная со значением "?", то результатом вычисления по этой формуле будет символ "?". Примеры:
:ХА=2,5+?С.+3,6.(1,4-?К1.)*
Переменная может перевычисляться через свое значение:
:ХТ=?Т.+1*
В этом примере значением Т будет его прежнее значение, которое оно имело до появления этого оператора, увеличенное на единицу. При вычислении арифметического выражения максимально допустимое число не должно превышать двадцати знаков. Если результат вычисления отрицательный, то числу присваивается знак "-", положительные числа и число ноль знака не имеют. Вычисления арифметических выражений позволяет получать реальную точность результатов 16-17 знаков, не зависимо от того целое это число или дробное. Примеры:
:ХАР1=100,05+1,1'Т1=200-300'=1,001+2,1*
В результате вычисления переменные примут следующие значения: АР1=101,15 Т1=-100 и 3,101;
:ХАР2=2С3'Т=Ц(3,33+1,1)'К=М(1-36)*
В этом примере переменные примут следующие значения: АР2=8; Т=4; К=35.
В арифметических выражениях знаки "+" и "-" обозначают бинарные операции сложения и вычитания, применять их для обозначения знака числа нельзя. В связи с этим, знак "+" у числа всегда опускается, а отрицательное число (например-5) следует записать в виде арифметического выражения: 0-5. Например, неправильная запись:
:ХСУММА=-200*
должна быть переписана так:
:ХСУММА=0-200*
Не допускается возводить в степень отрицательные числа, например, даст ошибку следующее выражение: :ХТ=(0-10)С2* или: :ХТ=0-10* :ХК=?Т.С2*
Наибольшие трудности, особенно у начинающих, возникают при использовании операторов типа :Х и строк типа Х, между которыми есть основное различие, состоящее в том, что арифметические выражения оператора : Х вычисляются на стадии трансляции стандартных фрагментов, а арифметические выражения в строках типа Х, а так же в других строках, где допускаются арифметические выражения (объемы, цены и т.д.), вычисляются при работе основных модулей системы АВС. Например, последовательность строк:
:ВТ=5'К=10* :ХМ=?Т..?К.+1* Х25+?М.=Ф1* Е1-15'Ф1.0,1.* ... после трансляции стандартных фрагментов даст результат:
Х25+51=Ф1* Е1-15'Ф1.0,1*,
а после работы модуля логического анализа получится следующий результат:
Е1-15'7,6*
|
<ПЕРЕХОД>::= :П{<целое,6> I К}*
Здесь <целое> определяет метку перехода и не должно содержать больше шести цифр. Запись :ПК" означает переход на конец стандартного фрагмента: в этой точке трансляция фрагмента прекращается и происходит переход к очередной строке исходных данных. Если при работе оператора "переход" не будет найдена нужная метка, то последует сообщение об ошибке. Пример оператора перехода: :П10* В этом случае управление перейдет на строку, начинающуюся с метки :М10, которая может быть самостоятельной строкой-меткой :М10*, обычной строкой :М10' <строка>* или оператором :М10' <оператор>* Значения меток в одном фрагменте могут повторяться: в этом случае они не должны перекрывать друг друга во время трансляции. Оператор ЕСЛИ позволяет передать управление на соответствующие метки, при выполнении некоторых условий, определенных в нем. <ЕСЛИ>::=:Е<условие>['Е<условие>] ... '{<метка 1> I К}'{<метка 2> IК}* где: <условие>::=<идентификатор переменной><отношение> {<значение> I <идентификатор переменной>} <метка 1> и <метка 2> есть целые числа не более шести разрядов. Оператор ЕСЛИ может иметь запись еще в виде: <ЕСЛИ>::=:Е<условие>/Е<условие>[/Е<условие>]['Е<условие>] ... '{<метка 1> I К}'{<метка 2> IК}* В этом случае наклонная черта означает логическое ИЛИ вместо апострофа, означающего логическое И.
Как и для оператора :П, значение метки равное К означает переход на конец фрагмента. Для отношения используются следующие обозначения:
При знаке отношения "специальное равно" и "специальное не равно" значения правой и левой частей условия сравниваются посимвольно. Если все символы совпадают, то условие считается выполненным. Остальные знаки отношений понимаются в обычном математическом смысле, а значениями идентификаторов переменных в этом случае должны быть числа. Если все условия в операторе ЕСЛИ выполняются, то управление переходит на метку 1, если же хотя бы одно условие не выполняется, - управление получает метка 2. В случае, когда какая-нибудь переменная не определена, или ее значение равно "?", оператор условного перехода пропускается и выполняется следующая за ним строка. В первой части условия может содержаться постоянное значение в виде последовательности символов или числа, а также идентификатор переменной выделенный с двух сторон символами "?" и ".".
Примеры: с использованием логического И :ЕА=?Т.'ЕВ(=)100,5'1'2* :ЕВ=5'ЕТ(=)?К.'8'12*
Переход в операторе :Е выполняется только вниз от оператора, пока не будет найдена метка, определенная этим оператором, например, при выполнении всех условий в операторе:
:ЕА=1'ЕБ=2'100'200* переход будет осуществлен на метку :М100 и, если хотя бы одно условие не выполнено, на метку :М200.
Примеры: с использованием логического ИЛИ, И :ВА=100'Б=200’В=300* :ЕА=50/ЕА=100’Б=200'ЕВ=300'10'11*
В этом случае все условия выполняются и переход в операторе :Е выполняется на метку :М10.
:ВА=100'Б=200’В=300* :ЕА=50/ЕА=100’Б=200'ЕВ=400'10'11* В этом случае не все условия выполняются и переход в операторе :Е выполняется на метку :М11*
Рассмотрим небольшой пример с применением операторов перехода: Ф27-164'Т* Е27-164'?ПЛ.* :ЕТ)=4,5'1'2* :М1':ВВП=* :П3* :М2':ЕТ(=3,5'4'К* :М4':ВВП=(ВП)* :М3'Е27-165?ВП.'?ПЛ..Ц(М(?Т.-4):0,5+0,01* <Ф* При обращении к фрагменту: ?27-164'ПЛ=100'Т=4* получим после трансляции: Е27-164'100* При обращении:
27-164'ПЛ=100'Т=5*
получим после трансляции:
Е27-164'100* Е27-165'100:Ц(М(5-4):0,5+0,01*
а после вычислений:
Е27-164'100* Е27-165'200*
При обращении:
27-164'ПЛ=100'Т=1,7*
получим после трансляции:
Е27-164'100* Е27-165(ВП)'100.Ц(М(1,7-4):0,5+0,01*
а после вычислений:
Е27-164'100* Е27-165(ВП)'400*
Напомним, что операция М в арифметических выражениях обозначает взятие модуля числа, т.е. М(а)= IАI, а буква Ц – взятие целой части числа, т.е. Ц(а)=[А], которое получается отбрасыванием дробной части. В приведенном примере продемонстрировано автоматическое присоединение дополнительной расценки с "добавлением" или "исключением" в зависимости от разницы толщины слоя в проекте по сравнению с учтенной в основной расценке толщиной равной 4см. Выражение Ц(М(?Т.-4):0,5+0,01) является целочисленной функцией от аргумента ?Т. и принимает значения целых чисел :0,1, 2 ...п. Например, при Т=3 последовательно получим: 3-4=-1 М(-1)=1 1:0,5=2 2+0,01=2,01 Ц(2,01)=2
Необходимость в дополнительном "малом" слагаемом 0,01 связана с тем, что в машине величина, например 2, может иметь, в результате внутренних преобразований, приближенное значение 1,999... и применение операции Ц(1,999...) даст 1, что привело бы к неверному результату.
Еще один логический оператор ПРОВЕРИТЬ НАЗНАЧЕНИЯ имеет следующий вид:
<ПРОВЕРИТЬ НАЗНАЧЕНИЯ>::=:Н<переменная>[/<переменная>] ... '{<метка 1> I К}'{<метка 2> IК}* где <переменная>::=<[+]переменная>;
Знак “+” перед переменной означает, что значение этой переменной должно быть числовым или корректным арифметическим выражением.
Оператор ПРОВЕРИТЬ НАЗНАЧЕНИЯ используется для предварительного определения, есть ли у переменных реальные значения или таковые отсутствуют. При подготовке к работе фрагмента такая предварительная проверка переменных, позволяет более корректно обрабатывать различные алгоритмы и расчеты в СФ. Если все значения у переменных определены (т.е. не равны пусто, не равны знаку ?, не определены переменные к моменту вызова оператора :Н..., не равны числовому значению или корректному арифметическому выражению если переменная имеет признак + ), то происходит переход по первой метке. В противном случае переход по второй метке, если хотя бы одна переменная из списка не определена.
Пример:
:НТИП/КРАН/+ОБЪЕМ'10'20* :М10* 1-строка* :П30* :М20* 2-строка* :М30*
Если все значения у переменных определены, то переход будет осуществлен на работу первой строки, в противном случае переход будет осуществлен на работу второй строки.
|
Оператор ЦИКЛ позволяет многократно повторить группу строк во фрагменте: <ЦИКЛ>::=<заголовок цикла> <строка> ... <конец цикла> где: <заголовок цикла>::=:Ц<переменная>['<переменная>]...* <конец цикла>::=:Ц* Все строки фрагмента, заключенные между заголовком цикла и концом цикла, образуют тело цикла. Тело цикла может содержать внутри себя простые строки и операторы, за исключением самих операторов цикла: вложенные циклы не предусмотрены. Не допускается в теле цикла перевычислять или вводить переменные, перечисленные в заголовке цикла. С помощью операторов перехода допускается выход за пределы цикла. Если хотя бы одна переменная заголовка цикла будет не определена к моменту выполнения цикла, то дальнейшее управление перейдет на строку следующую за концом цикла, т.е. все строки тела цикла опускаются в этом случае без обработки. Оператор ЦИКЛ работает следующим образом. Перечисленные в заголовке цикла переменные обычно определяются как одномерные массивы. При каждом прохождении цикла эти переменные принимают свои очередные значения. Цикл будет повторяться до тех пор, пока не кончатся все значения хотя бы у одной переменной заголовка цикла. Пусть переменные определены так: А=1'=2'=3 В=Ф1'=Ф2 С=15'=16'=24'=47 тогда после выполнения оператора цикла: :Ц А'В* Е15-?А.'?С.* Е10-?А.'?В.* :Ц* в текст-результат запишутся следующие строки: Е15-1'15* Е10-1'Ф1* Е15-2'15* Е10-2'Ф2* Цикл повторился два раза, поскольку переменная В определена только двумя значениями. Переменная С не входит в заголовок цикла, поэтому она принимает только свое первое значение. Если хотя бы одна переменная цикла отсутствует по умолчанию, то все тело цикла опускается. Этим обстоятельством можно воспользоваться, например, так: Ф1-12'Т* :Ц Т1* <строка 1> <строка 2>1-я группа строк ... <строка N> :Ц* :Ц Т2* <строка N+1> <строка N+2> 2-я группа строк ... <строка N+м> :Ц* <Ф* При обращении: ?1-12'Т1=* получаем в качестве результата трансляции первую группу строк, а при обращении:?1-12'Т2=* - вторую группу строк. Рассмотрим пример применения открытой строки и оператора ЦИКЛ для автоматического формирования арифметического выражения с переменным количеством слагаемых. Эту задачу можно решить с помощью следующего стандартного фрагмента: Ф225'Т* Х0=Ф1* -ХФ1* :Ц МС* -+?МС.* :Ц* =Ф1* <Ф* При обращении:
Т225'МС=23,4'=18,6'=44,2*
в результате трансляции СФ получим:
Х0=Ф1* ХФ1+23,4+18,6+44,2=Ф1*
Если, например, переменную МС не задать в обращении к ФС, т.е. записать Т225*, то получим после трансляции ФС:
Х0=Ф1* ХФ1=Ф1*
В рассмотренном варианте оператор ЦИКЛ заканчивает свою работу, если хотя бы один из массивов исчерпался (принцип минимального вектора). На практике, однако, чаще всего применяются массивы с равными количествами значений переменных. Использование окончания оператора ЦИКЛ по минимальному массиву практически не находит интересных применений. Значительно большие возможности представляет такая работа оператора ЦИКЛ, когда количеством повторений цикла управляет не минимальный, а максимальный вектор цикла (принцип максимального вектора). В этом случае для всех остальных переменных, имеющих меньшее количество переменных чем у максимального вектора, принимаются значения последнего (или единственного) элемента в каждом "коротком" векторе. Таким образом, переменные цикла можно представить в виде прямоугольной матрицы, где строками являются значения отдельных переменных, а столбцами - очередные значения переменных при каждом прохождении цикла, при этом, недостающие элементы отбрасываются (в случае принципа минимума) или "размножаются" путем тиражирования значения последнего элемента каждого короткого вектора до максимального (в случае принципа максимума). Пусть, например, имеется оператор ЦИКЛ:
:Ц А ' В ' С*
со следующими значениями переменных:
А = 5,6 2,4 В = ПЕСОКЩЕБЕНЬ ГРАВИЙ С = К2 Применение принципа минимума приводит к следующей таблице переменных: А = 5,6 В = ПЕСОК С = К2
и оператор ЦИКЛ проработает один раз. Применение принципа максимума приводит к следующей таблице значений переменных:
А = 5,6 2,4 2,4 В = ПЕСОК ЩЕБЕНЬ ГРАВИЙ С = К2 К2 К2
и оператор ЦИКЛ проработает три раза. Заметим, что физического размножения данных в памяти машины не происходит, так как оно выполняется на логическом уровне и расходования дополнительной памяти при этом не происходит. Полезность принципа максимума в операторе ЦИКЛ особенно проявляется для тех параметров, которые в одном случае могут иметь фиксированное значение, а в другом - индивидуальные значения для каждого конкретного случая. Так, например, при прокладке трубопроводов, состояние грунта на площадке может быть одним для всех участков и тогда его желательно указать один раз, но если такое решение будет жестко принято в стандартном фрагменте, то возникнут затруднения для его применения, когда грунт на площадке будет неоднородным. Аналогичные ситуации возникают и при описании глубины заложения, типа труб и во многих других случаях. Оператор ЦИКЛ в случае применения принципа максимума записывается в виде:
:Ц + <список переменных цикла>*
Оператор ЦИКЛ в случае принципа минимума записывается в виде:
:Ц[-]<список переменных цикла>*
т.е., для принципа минимума допускается и ранее применявшаяся запись:
:Ц<список переменных цикла>*
Реализован еще один тип оператора ЦИКЛ, работающий в режиме счетчика. Запись заголовка оператора цикла в этом случае представляется следующим образом:
<заголовок цикла>::=:Ц?<переменная>.*
Значением переменной может быть любое положительное целое число. Это число определяет количество повторений просмотра тела цикла. Все переменные в теле такого цикла принимает только первые или единственные свои значения. Переменная заголовка цикла в теле цикла не перевычисляется. Если переменная тела цикла отсутствует по умолчанию или имеет в качестве значения символ ?, то в этих случаях тело оператора цикла опускается. Оператор цикла в режиме счетчика может применяться для приближенных итерационных вычислений с предельным значением повторения числа шагов итерационного процесса и др.
|
Оператор логическая ТАБЛИЦА или "переход по случаю" имеет следующую общую структуру:
<ТАБЛИЦА>::=:Т<идентификатор переменной><отношение>{<значение>I<идентификатор переменной>.} ['<отношение>{<значение>I<идентификатор переменной>}]...*
Оператор таблица рассматривается совместно с N+I последующими строками стандартного фрагмента, где N-количество отношений в операторе. Переход осуществляется к выполнению строки I, номер следования которой совпадает с порядковым номером первого выполнившегося отношения в операторе таблица. После выполнения этой строки происходит переход к выполнению N+2 строки. Если ни одно из отношений оператора таблица не выполнится, то произойдет переход к выполнению N+1 строки. Пример: :ТНОМЕР=1'=2'=3'=4* Е1-48'Ф1* Е1-92'Ф1.0,1* Е1-104'Ф1+Ф2.0,5* Е1-127'Ф1* :ОШИБКА - НЕВЕРНО ЗАДАН НОМЕР* Е1-218'Ф1+Ф2* При НОМЕР=3 получится следующий результат: Е1-104'Ф1+Ф2.0,5* Е1-128'Ф1+Ф2* При НОМЕР=25 получится: :ОШИБКА - НЕВЕРНО ЗАДАН НОМЕР* Е1-218'Ф1+Ф2* Из рассмотренного примера видно, что работу оператора ТАБЛИЦА можно представить следующим образом. Проверяется первое условие: если оно выполняется, то берется первая строка: если же первое условие не выполняется, то первая строка опускается и проверяется второе условие и т.д. Если выполняется I-ое по порядку условие, то в общем случае происходит следующее: пропускается N-I строка, обрабатывается I-ая строка, пропускаются остальные строки до N+1 включительно. Если не выполняется ни одно условие: пропускаются N последовательных строк и выполняется N+1 строка, которая нередко применяется для вывода информации об ошибке, но может применяться и для любых других целей. В качестве знаков отношения в операторе ТАБЛИЦА применяются те же знаки отношений, что и для оператора ЕСЛИ. Значение идентификатора переменной левой части может сравниваться с постоянным значением или значением переменной правой части отношения. Идентификатор переменной в правой части должен выделяться с двух сторон символами "?" и ".". Значение переменной в левой части будет сравниваться со значением переменной правой части, например: :ВТ=ЩЕБЕНЬ* ... :ВМ=ГРАВИЙ* ... :ВК(=) ?М.'(=) ?Т.* ... здесь переменная К будет сравниваться с переменными М и Т. Если переменная левой части оператора ТАБЛИЦА отсутствует по умолчанию или имеет значение "?", то происходит переход к выполнению N+2 строки. В качестве строк оператора ТАБЛИЦА могут быть различные операторы и строки. Если в качестве выполняемой строки будет один из операторов: ПЕРЕХОД, ЕСЛИ или ЦИКЛ, то выполняться этот оператор будет обычным образом, т.е. пропуск до N+2 строки не выполняется, а выполняется переход, который предписывается этим оператором. Отметим, что сам оператор таблица может быть в области действия оператора ЦИКЛ. Если в качестве выполняемой строки оператора ТАБЛИЦА будет сам оператор ТАБЛИЦА, то такой оператор будет называться внутренним оператором ТАБЛИЦА, а содержащий его оператор внешним. После выполнения внутреннего оператора ТАБЛИЦА управление передается на внешний оператор ТАБЛИЦА. Глубина вложения оператора ТАБЛИЦА друг в друга не ограничена. Если внутренний оператор ТАБЛИЦА попадает в качестве пропускаемой строки, то он пропускается вместе со всеми N+1 строкой и далее работает внешний оператор ТАБЛИЦА. Иначе говоря, для внешнего оператора ТАБЛИЦА внутренний оператор ТАБЛИЦА с его N+1 строками воспринимается как одна строка. В следующем разделе будет рассмотрен другой способ объединения нескольких строк в одну выполняемую строку с перезаписью в текст-результат всей такой группы. Часто возникает необходимость выборки номеров расценок, коэффициентов или каких-либо других из двумерных таблиц. Рассмотрим пример таблицы, которая определена двумя переменными А и Б, где каждой паре (А, Б) соответствует некоторое значение АI: А/Б Б1 Б2 Б3 Б4 А1а1 а2 а3 а4 А2а5 а6 а7 а8 А3а9 а10 а11 а12 Покажем, как можно найти а1 в зависимости от различных значений А и Б с применением оператора ТАБЛИЦА: ... :ТА(=)А1'(=)А2'(=)А3* :ТБ(=)Б1'(=)Б2'(=)Б3'(=)Б4* <а1> <а2> <а3> <а4> :О ОШИБКА В Б 4* :ТБ(=)Б1'(=)Б2'(=)Б3'(=)Б4* <а5> <а6> <а7> <а8> :О ОШИБКА В Б* :ТБ(=)Б1'(=)Б2'(=)Б3'(=)Б4* <а9> <а10> <а11> <а12> :О ОШИБКА В Б* :О ОШИБКА В А* ... (Оператор ОШИБКА см. ниже).
Из этого примера видно, что каждый паре переменных А и Б соответствует своя строка <аI>, которая может быть обычной базисной строкой или содержать оператор, разрешенный в операторе ТАБЛИЦА. Оператор ТАБЛИЦА можно использовать как "укороченный" оператор ЕСЛИ, например: :ТВАР=1* Е48-50'Ф230* :О ОШИБКА В ВАРИАНТЕ* Этот же пример с использованием оператора ЕСЛИ имел бы вид: :ЕВАР=1'10'11* :П12* :М10'Е48-50'Ф230* :П12* :М11':О ОШИБКА В ВАРИАНТЕ* :М12* ... Видно, что из соображений компактности записи предпочтение можно отдать первому варианту.
|
Оператор БЛОК предназначен для совместной работы с оператором ТАБЛИЦА, вне области действия оператора ТАБЛИЦА этот оператор никакого действия не производит. Как было рассмотрено выше, оператор ТАБЛИЦА работает вместе с N+1 строкой, где каждая строка - обычная строка или оператор. Во многих случаях удобно, чтобы в качестве "строки" оператора ТАБЛИЦА рассматривалась группа последовательных строк, которая как одно целое могла бы опускаться или переписываться в текст-результат. Для реализации такой возможности применяется оператор БЛОК: <БЛОК>::=<начало блока> <строка> ... <конец блока> где: <начало блока>::=Б* <конец блока> ::=БК* Если в операторе ТАБЛИЦА данные оформлены в виде блоков, то каждый из них обрабатывается как самостоятельная строка. Блоки и обычные строки могут чередоваться произвольным образом. Включение внутрь блока другого блока или оператора ТАБЛИЦА не допускается. Внутри блока можно использовать операторы :Ц, :Е, :П, :М, но в этих случаях передачи управления могут быть только к строкам в пределах данного блока. Пример: :ТА1(=)ВАРИАНТ 1'(=)ВАРИАНТ 2'(=)ПРОЧИЕ* :Б* П РАЙОН 20* П ПАРАМЕТР Н=16* :БК* :Б* П РАЙОН 21* П ПАРАМЕТР Н=42* Р МОНТАЖНЫЕ РАБОТЫ* : БК* П ПРИМЕНЯЮТСЯ СТАНДАРТНЫЕ ПАРАМЕТРЫ* :ОШИБКА В ЗАДАНИИ ЗОНЫ* ... При выполнении условия А1(=)ВАРИАНТ 2, получим в тексте-результате: П РАЙОН 21* П ПАРАМЕТР Н=42* Р МОНТАЖНЫЕ РАБОТЫ*
|
Оператор КОММЕНТАРИЙ записывается по следующему общему правилу:
<КОММЕНТАРИЙ>::=:К<текст>*
где в качестве текста используется любая последовательность символов без применения символа "*". Оператор КОММЕНТАРИЙ используется в теле СФ для записи различных пояснений к содержанию фрагмента. Количество таких операторов и их расположение во фрагментах произвольно. На результат работы транслятора эти операторы никакого влияния не оказывают. Обычно рекомендуется в первых строках стандартного фрагмента записывать с помощью оператора КОММЕНТАРИЙ следующие данные: - для какой цели разработан стандартный фрагмент; - кем и когда разработан; - перечень переменных параметров: их назначение и пример задания. Могут дополнительно указываться и любые другие данные. По мере записи фрагмента также рекомендуются различные комментарии, облегчающие его понимание при изучении другими пользователями. Примеры текстов комментариев:
:К ФРАГМЕНТ ЛОКАЛЬНОЙ СМЕТЫ ВОДОСНАБЖЕНИЯ* :К РАЗРАБОТАН В ИНСТИТУТЕ ВОДОКАНАЛПРОЕКТ ПЕТРОВЫМ П.П., ТЕЛ. 25-12-68* :К ПЕРЕЧЕНЬ ПЕРЕМЕННЫХ:* :К КУ - КОЛИЧЕСТВО УЧАСТКОВ* :К ДУ - ДЛИНА УЧАСТКОВ" и т.д.
|
Оператор вывода информации об ошибках
Оператор ОШИБКА позволяет организовать вывод на печать сообщений о неправильном использовании стандартного фрагмента. Синтаксис оператора ОШИБКА:
<ОШИБКА>::=О<текст>*
Здесь в качестве текста может использоваться любая последовательность символов, без использования символа "*". Текст сообщения об ошибке формирует таким образом, чтобы информировать пользователя о характере допущенной ошибки, в нем же можно давать рекомендации как правильно поступить в том или ином случае. Хорошее использование оператора ОШИБКА позволяет вводить в стандартных фрагментах элементы обучающей системы. При обнаружении ошибок, тексты сообщения об ошибках выдаются на печать в разделе информации об ошибках, а сами данные, содержащие ошибки, из дальнейших расчетов исключаются. Рассмотрим пример. Пусть в некотором стандартном фрагменте наличие переменных: БЕТОН, ПЕСОК, АРМАТУРА, ОПАЛУБКА строго обязательны. Проверку их наличия и сообщения об ошибке если хотя бы один из них будет отсутствовать, можно выполнить следующим образом: ... :ЕБЕТОН(=)'ЕАРМАТУРА(=)'ЕПЕСОК(=)'ЕОПАЛУБКА(=)'1'1* :О ОШИБКА: НЕОБХОДИМО ЗАДАТЬ ОБЯЗАТЕЛЬНЫЕ ПАРАМЕТРЫ: БЕТОН, АРМАТУРА, ПЕСОК, ОПАЛУБКА.* :ПК* :М1* ... Если хотя бы один параметр не будет задан, или его наименование будет записано с ошибкой, то появится сообщение об ошибке. Однако этот вариант не указывает конкретно какая из переменных отсутствует. Следующая последовательность операторов может дать желаемый результат:
:ЕВАР(=)'10'10* :О НЕ ЗАДАН ИДЕНТИФИКАТОР ВАР* :М10* :ЕНОМ(=)'11'11* :О НЕ ЗАДАН ИДЕНТИФИКАТОР НОМ* :М11* :ЕКОЛ(=)'12'12* :О НЕ ЗАДАН ИДЕНТИФИКАТОР КОЛ* :М12* ... |