По мотивам - Обработка текстов. Генераторы, фильтры, трансформаторы и "SAX на коленке"
ToDo. Сделать парсинг "старых шаблонов" через построение дерева разбора.
Т.е. не сразу пишем в файл, а сначала строим дерево разбора, а потом это дерево разбора сохраняем в файл.
Почти в "любой язык".
То есть сначала приводим данные "к единому знаменателю", а потом переводим эти данные в другой формат.
Вот тут:
https://bitbucket.org/lulinalex/mindstream/commits/4f552de74c82dea069e168d8f81822ecae49f6aa
ToDo. Сделать парсинг "старых шаблонов" через построение дерева разбора.
Т.е. не сразу пишем в файл, а сначала строим дерево разбора, а потом это дерево разбора сохраняем в файл.
Почти в "любой язык".
То есть сначала приводим данные "к единому знаменателю", а потом переводим эти данные в другой формат.
Вот тут:
https://bitbucket.org/lulinalex/mindstream/commits/4f552de74c82dea069e168d8f81822ecae49f6aa
USES 'W:\shared\models\NewSchool\Templates\MDATuning.tpl.script' ; : "Ничего не делаем" ; // "Ничего не делаем" : log . //DROP ; // log WORDWORKER "начинается с" W-STRING IN aStr WordToWork DO aStr WString:Starts ; // "начинается с" // InitedVarProducer VAR-I : "Обработать шаблоны MDA" ARRAY VAR "Обработанные файлы" FORWARD "Обработать файл" : "Обработать файл" STRING IN "Имя входного файла" "Обработанные файлы" "Имя входного файла" array:HasText ? ( [ 'duplicated: ' "Имя входного файла" ' skipped' ] strings:Cat log EXIT ) // "Обработанные файлы" "Имя входного файла" array:HasString ? "Имя входного файла" >>>[] "Обработанные файлы" STRING VAR "Путь к входному файлу" "Имя входного файла" sysutils:ExtractFilePath =: "Путь к входному файлу" "Путь к входному файлу" log VAR "Имя выходного файла" "Имя входного файла" '.script' Cat =: "Имя выходного файла" CONST "Пробел" ' ' CONST "Пустая строка" '' CONST "Кавычка" '''' CONST "Открывающаяся скобка" '(' CONST "Закрывающаяся скобка" ')' CONST "Запятая" ',' CONST "Знак процента" '%' CONST "Спецсимволы" '\%[]{}<>#()' CONST "Цифры" '1234567890' CONST "Разделитель частей стереотипа" '::' STRING VAR "Имя диска" "Имя выходного файла" sysutils:ExtractFileDrive =: "Имя диска" '\' string:SplitTo! "Имя выходного файла" "Имя диска" ?== 'Имя файла не содержит указание диска' ASSERTS [ "Имя диска" '\NewSchool\' "Имя выходного файла" ] strings:Cat =: "Имя выходного файла" "Имя выходного файла" log STRING VAR "Путь к выходному файлу" "Имя выходного файла" sysutils:ExtractFilePath =: "Путь к выходному файлу" "Путь к выходному файлу" log "Путь к выходному файлу" sysutils:ForceDirectories 'Не удалось создать директории' ASSERTS //script:FileName sysutils:ExtractFileName "Пустая строка" "Пробел" Cat "Имя выходного файла" sysutils:ExtractFileName Cat =: "Имя выходного файла" FILE VAR "Входной файл" "Имя входного файла" file:OpenRead =: "Входной файл" TRY FILE VAR "Выходной файл" "Имя выходного файла" file:OpenWrite =: "Выходной файл" TRY W-STRING VAR "Текущая строка входного файла" : "Строка пустая" "Текущая строка входного файла" WString:IsNil ; // "Строка пустая" WORDWORKER "Строка начинается с" VAR l_Begin WordToWork DO =: l_Begin "Текущая строка входного файла" "начинается с" l_Begin ; // "Строка начинается с" WORDWORKER "Строка равна" VAR l_EQ WordToWork DO =: l_EQ "Текущая строка входного файла" l_EQ ?== ; // "Строка начинается с" BOOLEAN VAR "Накапливаемая строка пустая" BOOLEAN VAR "Была кавычка" : "Вывести строку" "Выходной файл" file:WriteStr ; // "Вывести строку" : "Вывести кавычку" "Кавычка" "Вывести строку" ; // "Вывести кавычку" : "Закрыть кавычку, если была" "Была кавычка" ? ( "Вывести кавычку" false =: "Была кавычка" ) // "Была кавычка" ? ; // "Закрыть кавычку, если была" : "Вывести пробел" "Пробел" "Вывести строку" ; // "Вывести пробел" : "Сбросить накопленную строку без перевода" "Накапливаемая строка пустая" ! ? ( "Закрыть кавычку, если была" "Вывести пробел" true =: "Накапливаемая строка пустая" false =: "Была кавычка" ) // "Накапливаемая строка" string:Len !=0 ? ; // "Сбросить накопленную строку без перевода" BOOLEAN VAR "Был отступ" : "Перевести строку" "Закрыть кавычку, если была" "Пустая строка" "Выходной файл" file:WriteLn false =: "Был отступ" "Была кавычка" ! 'Похоже не закрыли кавычку' ASSERTS //false =: "Была кавычка" ; // "Перевести строку" : "Сбросить накопленную строку" "Накапливаемая строка пустая" ! ? ( "Закрыть кавычку, если была" "Перевести строку" true =: "Накапливаемая строка пустая" ) // "Накапливаемая строка" string:Len !=0 ? ; // "Сбросить накопленную строку" : "Сбросить накопленную строку, чтобы кавычка случайно не переехала на другую строку" "Сбросить накопленную строку" ; // "Сбросить накопленную строку, чтобы кавычка случайно не переехала на другую строку" : "Вывести строку как есть" "Текущая строка входного файла" "Выходной файл" file:WriteWStrLn ; // "Вывести строку как есть" : "Добавить к строке / и вывести" "Сбросить накопленную строку, чтобы кавычка случайно не переехала на другую строку" '/' "Вывести строку" "Вывести строку как есть" ; // "Добавить к строке / и вывести" : "Вывести строку как комментарий. Чтобы в конечном файле было с чем сравнивать" "Сбросить накопленную строку, чтобы кавычка случайно не переехала на другую строку" "Был отступ" ? "Перевести строку" '//' "Вывести строку" "Вывести строку как есть" false =: "Был отступ" ; // "Вывести строку как комментарий. Чтобы в конечном файле было с чем сравнивать" BOOLEAN VAR "Был открыт стереотип" false =: "Был открыт стереотип" STRING VAR "Имя стереотипа" "Пустая строка" =: "Имя стереотипа" STRING VAR "Имя класса стереотипа" "Пустая строка" =: "Имя класса стереотипа" STRING VAR "Имя под-стереотипа" "Пустая строка" =: "Имя под-стереотипа" STRING VAR "Имя класса под-стереотипа" "Пустая строка" =: "Имя класса под-стереотипа" STRING VAR "Имя под-под-стереотипа" "Пустая строка" =: "Имя под-под-стереотипа" STRING VAR "Имя класса под-под-стереотипа" "Пустая строка" =: "Имя класса под-под-стереотипа" BOOLEAN VAR "Была открыта функция" false =: "Была открыта функция" STRING VAR "Имя функции" "Пустая строка" =: "Имя функции" BOOLEAN VAR "Был открыт трансформатор" false =: "Был открыт трансформатор" STRING VAR "Имя трансформатора" "Пустая строка" =: "Имя трансформатора" BOOLEAN VAR "Был открыт генератор" false =: "Был открыт генератор" STRING VAR "Имя генератора" "Пустая строка" =: "Имя генератора" CONST Разделители ' ' CONST "Двойная кавычка" '"' CONST "Параметр Self" ' OBJECT IN %S' CONST "Скобка закрытия функции" '; // ' CONST "Открываем строку стереотипа" '<<' CONST "Закрываем строку стереотипа" '>>' CONST "Табуляция" #9 : "Вывести строку с переводом строки" "Вывести строку" "Перевести строку" ; // "Вывести строку с переводом строки" : "Вывести исходную строку" "Текущая строка входного файла" "Выходной файл" file:WriteWStr ; // "Вывести исходную строку" : "Записать имя стереотипа" Если ( "Имя под-стереотипа" string:Len !=0 ) то ( ':: ' "Вывести строку" "Имя стереотипа" "Вывести строку" "Пробел" "Вывести строку" "Имя под-стереотипа" "Вывести строку" Если ( "Имя под-под-стереотипа" string:Len !=0 ) то ( "Пробел" "Вывести строку" "Имя под-под-стереотипа" "Вывести строку" ) // "Имя под-под-стереотипа" string:Len !=0 ' ;' "Вывести строку" ) иначе ( "Имя стереотипа" "Вывести строку" ) // "Имя под-стереотипа" string:Len !=0 "Перевести строку" ; // "Записать имя стереотипа" : "Записать имя функции" "Имя функции" "Вывести строку" ; // "Записать имя функции" : "Записать имя трансформатора" "Имя трансформатора" "Вывести строку" ; // "Записать имя трансформатора" : "Записать имя генератора" "Имя генератора" "Вывести строку" ; // "Записать имя генератора" FORWARD "Закрыть вложенные опеределения" : "Закрыть стереотип" "Был открыт стереотип" ? ( "Закрыть вложенные опеределения" 'end. // ' "Вывести строку" "Записать имя стереотипа" "Перевести строку" ) // "Был открыт стереотип" ? false =: "Был открыт стереотип" ; // "Закрыть стереотип" INTEGER VAR "Отступ" INTEGER VAR "Количество открытых IF" INTEGER VAR "Количество открытых циклов" INTEGER VAR "Количество открытых скобок параметров функции" STRING VAR "Аргумент цикла" "Аргумент цикла" := '' BOOLEAN VAR "Был признак переноса" "Был признак переноса" := НЕТ : "Закрыть все скобки" 0 =: "Отступ" 0 =: "Количество открытых IF" 0 =: "Количество открытых циклов" 0 =: "Количество открытых скобок параметров функции" "Закрыть вложенные опеределения" "Закрыть стереотип" ; // "Закрыть все скобки" : "Закавычить имя стереотипа" Разделители "Имя стереотипа" string:HasAnyOf ? ( [ "Двойная кавычка" "Имя стереотипа" "Двойная кавычка" ] strings:Cat =: "Имя стереотипа" ) "Имя класса стереотипа" 'MDAGenerator' ?!= ? ( [ "Открываем строку стереотипа" "Имя стереотипа" "Закрываем строку стереотипа" ] strings:Cat =: "Имя стереотипа" ) ; // "Закавычить имя стереотипа" : "Закавычить имя под-стереотипа" "Имя под-стереотипа" string:Len !=0 ? ( Разделители "Имя под-стереотипа" string:HasAnyOf ? ( [ "Двойная кавычка" "Имя под-стереотипа" "Двойная кавычка" ] strings:Cat =: "Имя под-стереотипа" ) // Разделители "Имя под-стереотипа" string:HasAnyOf ? // "Имя класса стереотипа" 'MDAGenerator' ?!= true ? ( [ "Открываем строку стереотипа" "Имя под-стереотипа" "Закрываем строку стереотипа" ] strings:Cat =: "Имя под-стереотипа" ) // true ? ) // "Имя под-стереотипа" string:Len !=0 ? ; // "Закавычить имя под-стереотипа" : "Открыть стереотип" "Был открыт стереотип" ! ? ( 'implementation @ ' "Вывести строку" "Записать имя стереотипа" true =: "Был открыт стереотип" ) // "Был открыт стереотип" ! ; // "Открыть стереотип" : "Разобрать заголовок стереотипа" "Закрыть стереотип" 2 WString:+! "Текущая строка входного файла" "Текущая строка входного файла" WString:ToString =: "Имя стереотипа" "Имя стереотипа" "Разделитель частей стереотипа" string:Split =: "Имя класса стереотипа" =: "Имя стереотипа" "Имя класса стереотипа" "Разделитель частей стереотипа" string:Split =: "Имя под-стереотипа" =: "Имя класса стереотипа" "Имя под-стереотипа" "Разделитель частей стереотипа" string:Split =: "Имя класса под-стереотипа" =: "Имя под-стереотипа" "Имя класса под-стереотипа" "Разделитель частей стереотипа" string:Split =: "Имя под-под-стереотипа" =: "Имя класса под-стереотипа" "Закавычить имя стереотипа" "Закавычить имя под-стереотипа" "Открыть стереотип" ; // "Разобрать заголовок стереотипа" : "Закрыть функцию" "Была открыта функция" ? ( "Скобка закрытия функции" "Вывести строку" "Записать имя функции" "Перевести строку" "Перевести строку" ) false =: "Была открыта функция" ; // "Закрыть функцию" : "Закрыть трансформатор" "Был открыт трансформатор" ? ( "Скобка закрытия функции" "Вывести строку" "Записать имя трансформатора" "Перевести строку" "Перевести строку" ) false =: "Был открыт трансформатор" ; // "Закрыть трансформатор" : "Закрыть генератор" "Был открыт генератор" ? ( "Скобка закрытия функции" "Вывести строку" "Записать имя генератора" "Перевести строку" "Перевести строку" ) false =: "Был открыт генератор" ; // "Закрыть генератор" // : "Было открыто хоть одно вложенное определение" // "Была открыта функция" ИЛИ // "Был открыт трансформатор" ИЛИ // "Был открыт генератор" // ; // "Было открыто хоть одно вложенное определение" : "Закрыть вложенные опеределения" "Закрыть генератор" "Закрыть функцию" "Закрыть трансформатор" false =: "Был отступ" ; // "Закрыть вложенные опеределения" : "Записать параметры функции" BOOLEAN IN aGlobal "Параметр Self" "Вывести строку" ; // "Записать параметры функции" : "Записать параметры трансформатора" BOOLEAN IN aGlobal "Параметр Self" "Вывести строку" ; // "Записать параметры трансформатора" : "Разобрать заголовок функции" BOOLEAN IN aGlobal "Закрыть вложенные опеределения" Если aGlobal то "Закрыть стереотип" иначе "Открыть стереотип" Если aGlobal то ( 2 WString:+! "Текущая строка входного файла" // - отрезаем f ) иначе ( 3 WString:+! "Текущая строка входного файла" // - отрезаем %f ) "Строка начинается с" '_' ? WString:++! "Текущая строка входного файла" // - отрезаем поддчёркивание "Текущая строка входного файла" WString:ToString =: "Имя функции" // - получаем имя текущей функции ': ' "Вывести строку" "Записать имя функции" aGlobal "Записать параметры функции" "Перевести строку" true =: "Была открыта функция" ; // "Разобрать заголовок функции" : "Разобрать заголовок трансформатора" IN aGlobal "Закрыть вложенные опеределения" Если aGlobal то "Закрыть стереотип" иначе "Открыть стереотип" Если aGlobal то ( 2 WString:+! "Текущая строка входного файла" // - отрезаем t ) иначе ( 3 WString:+! "Текущая строка входного файла" // - отрезаем %t ) "Строка начинается с" '_' ? WString:++! "Текущая строка входного файла" // - отрезаем поддчёркивание "Текущая строка входного файла" WString:ToString =: "Имя трансформатора" // - получаем имя текущего трансформатора '<<transformator>> ' "Вывести строку" "Записать имя трансформатора" aGlobal "Записать параметры трансформатора" "Перевести строку" true =: "Был открыт трансформатор" ; // "Разобрать заголовок трансформатора" : "Разобрать заголовок функции стереотипа" false "Разобрать заголовок функции" ; // "Разобрать заголовок функции стереотипа" : "Разобрать заголовок глобальной функции" true "Разобрать заголовок функции" ; // "Разобрать заголовок глобальной функции" : "Разобрать заголовок трансформатора стереотипа" false "Разобрать заголовок трансформатора" ; // "Разобрать заголовок трансформатора стереотипа" : "Разобрать заголовок глобального трансформатора" true "Разобрать заголовок трансформатора" ; // "Разобрать заголовок глобального трансформатора" : "Записать параметры генератора" "Параметр Self" "Вывести строку" ; // "Записать параметры генератора" : "Разобрать заголовок генератора" "Закрыть вложенные опеределения" 2 WString:+! "Текущая строка входного файла" "Текущая строка входного файла" WString:ToString =: "Имя генератора" "Открыть стереотип" '<<generator>> ' "Вывести строку" "Записать имя генератора" "Записать параметры генератора" "Перевести строку" true =: "Был открыт генератор" ; // "Разобрать заголовок генератора" BOOLEAN FUNCTION "Обрабатываем незначащие строки" BOOLEAN IN "Надо переводить строку" : "Вывести комментарий, котрый был в исходном файле" "Сбросить накопленную строку, чтобы кавычка случайно не переехала на другую строку" Если "Надо переводить строку" то "Перевести строку" иначе ( "Был отступ" ? "Перевести строку" ) // "Надо переводить строку" "Вывести строку как есть" ; // "Вывести комментарий, котрый был в исходном файле" : "Сигнализировать о неуспехе" false =: Result ; // "Сигнализировать о неуспехе" true =: Result // - будем оптимистами RULES "Строка пустая" ( "Закрыть кавычку, если была" "Надо переводить строку" ? "Перевести строку" "Вывести строку как есть" ) // "Строка пустая" "Строка начинается с" '//#UC END# *' ( "Вывести комментарий, котрый был в исходном файле" "Закрыть вложенные опеределения" // - т.к. наверное функция, трансформатор или генератор - закончились ) "Строка начинается с" '//' "Вывести комментарий, котрый был в исходном файле" "Строка начинается с" '/' ( "Надо переводить строку" ? "Перевести строку" "Добавить к строке / и вывести" ) // "Строка начинается с" '/' DEFAULT "Сигнализировать о неуспехе" ; // RULES ; // "Обрабатываем незначащие строки" : "Обрабатываем незначащие строки без перевода строки перед ними" false "Обрабатываем незначащие строки" ; // "Обрабатываем незначащие строки без перевода строки перед ними" : "Обрабатываем незначащие строки с переводом строки перед ними" true "Обрабатываем незначащие строки" ; // "Обрабатываем незначащие строки с переводом строки перед ними" : "Разбираем код функции шаблона с начала строки" : "Увеличить отступ" 1 +! "Отступ" ; // "Увеличить отступ" : "Уменьшить отступ" -1 +! "Отступ" ; // "Уменьшить отступ" : "Вывести отступ" "Был отступ" ! ? ( "Отступ" "Пробел" char:Dupe "Вывести строку" true =: "Был отступ" ) // "Был отступ" ! ? ; // "Вывести отступ" true =: "Накапливаемая строка пустая" false =: "Была кавычка" : "Открыть кавычку, если не было" "Была кавычка" ! ? ( "Вывести кавычку" true =: "Была кавычка" ) // "Была кавычка" ! ? ; // "Открыть кавычку, если не было" : "Вывести отступ, если накапливаемая строка пустая" "Накапливаемая строка пустая" ? "Вывести отступ" ; // "Вывести отступ, если накапливаемая строка пустая" : "Добавить спецстроку к накапливаемой строке" STRING IN aStr "Вывести отступ, если накапливаемая строка пустая" "Закрыть кавычку, если была" aStr "Вывести строку" // - пишем собственно спецстроку false =: "Накапливаемая строка пустая" ; // "Добавить спецстроку к накапливаемой строке" : "Выводим следующий символ как есть" "Текущая строка входного файла" WString:Len !=0 ? ( "Вывести отступ, если накапливаемая строка пустая" "Открыть кавычку, если не было" WString:[]++! "Текущая строка входного файла" DUP "Кавычка" ?== ? "Вывести кавычку" // - удваиваем кавычку "Выходной файл" file:WriteChar // - кладём символ в стек и сдвигаем указатель и пишем символ в файл false =: "Накапливаемая строка пустая" ) // "Текущая строка входного файла" WString:Len !=0 ? ; // "Выводим следующий символ как есть" : "Сбросить накопленную строку и вывести отступ" "Сбросить накопленную строку" "Вывести отступ" ; // "Сбросить накопленную строку и вывести отступ" : "По любому пишем пробел, чтобы не слипалось с последующими строками" "Вывести пробел" ; // По любому пишем пробел, чтобы не слипалось с последующими строками" : "Вывести значение для пустой строки" "Вывести кавычку" "Вывести кавычку" ; // "Вывести значение для пустой строки" : "Увеличить количество открытых скобок параметров функции" 1 +! "Количество открытых скобок параметров функции" ; // "Увеличить количество открытых скобок параметров функции" : "Уменьшить количество открытых скобок параметров функции" -1 +! "Количество открытых скобок параметров функции" ; // "Увеличить количество открытых скобок параметров функции" FORWARD "Обработать строку начинающуюся с % как начало цепочки" FORWARD "Обработать строку начинающуюся с % как вызов метода объекта" FORWARD "Один проход разбора остатка" : "Один проход разбора остатка без учёта его результата" "Один проход разбора остатка" DROP ; // "Один проход разбора остатка без учёта его результата" : "Увеличить количество открытых IF" 1 +! "Количество открытых IF" ; // "Увеличить количество открытых IF" : "Уменьшить количество открытых IF" -1 +! "Количество открытых IF" ; // "Уменьшить количество открытых IF" : "Увеличить количество открытых циклов" 1 +! "Количество открытых циклов" ; // "Увеличить количество открытых циклов" : "Уменьшить количество открытых циклов" -1 +! "Количество открытых циклов" ; // "Уменьшить количество открытых циклов" FORWARD "Разобрать фактические параметры условия" FORWARD "Разобрать параметры 1-й части цикла" //FORWARD "Разобрать параметры 3-й части цикла" FORWARD "Разобрать код ветки ELSE" FORWARD "Обрабатываем END-IF" FORWARD "Обрабатываем конец цикла" : "Обрабатываем условие" BOOLEAN IN "Нужен ли отступ" WString:++! "Текущая строка входного файла" // - отрезаем { //"Перевести строку" "Нужен ли отступ" ? "Вывести отступ" //"Вывести пробел" '( ' "Вывести строку" "Разобрать фактические параметры условия" //"Перевести строку" //"Вывести отступ" ') ' "Вывести строку" "Нужен ли отступ" ? "Перевести строку" ; // "Обрабатываем условие" : "Обрабатываем условие без отступа" false "Обрабатываем условие" ; // "Обрабатываем условие без отступа" : "Обрабатываем условие с отступом" false "Обрабатываем условие" ; // "Обрабатываем условие с отступом" FORWARD "Разобрать параметры тела IF" FORWARD "Обрабатываем тело END-IF" : "Обрабатываем IF" "Увеличить количество открытых IF" STRING VAR "Имя Файла для ELSE" "Имя Файла для ELSE" := '' FILE VAR "Файл для ELSE" "Файл для ELSE" := nil BOOLEAN VAR "Есть непустое условие" "Есть непустое условие" := ДА TRY WString:++! "Текущая строка входного файла" // - отрезаем [ //"Был отступ" ? "Перевести строку" "Сбросить накопленную строку и вывести отступ" "Есть непустое условие" := ( ( "Строка начинается с" '{' ) И НЕ ( "Строка начинается с" '{}' ) ) 'if' "Вывести строку" // - пишем "наш" IF Если "Есть непустое условие" то ( "По любому пишем пробел, чтобы не слипалось с последующими строками" ) иначе ( ' NOT-EMPTY' "Вывести строку" // - пишем "наш" IF, который будет проверять, что вычислились параметры "Перевести строку" ) // "Строка начинается с" '{' "Увеличить отступ" "Строка начинается с" '{' ? ( Если "Есть непустое условие" то ( "Обрабатываем условие без отступа" 'then' "Вывести строку" "Перевести строку" ) иначе ( WString:++! "Текущая строка входного файла" // - отрезаем { WString:++! "Текущая строка входного файла" // - отрезаем } ) ) // "Строка начинается с" '{' "Уменьшить отступ" "Вывести отступ" 'begin' "Вывести строку" "Увеличить отступ" "Перевести строку" "Строка начинается с" '{' ? ( "Имя Файла для ELSE" := ( [ "Имя выходного файла" '.' "Количество открытых IF" IntToStr '.if.txt' ] strings:Cat ) "Файл для ELSE" := ( "Имя Файла для ELSE" file:OpenWrite ) FILE VAR "Предыдущий Выходной файл" "Предыдущий Выходной файл" := nil "Предыдущий Выходной файл" := "Выходной файл" TRY "Выходной файл" := "Файл для ELSE" "Был отступ" := НЕТ WString:++! "Текущая строка входного файла" // - отрезаем { //"Перевести строку" "Уменьшить отступ" TRY "Вывести отступ" //"Вывести пробел" 'else' "Вывести строку" "Перевести строку" "Вывести отступ" 'begin' "Вывести строку" "Перевести строку" "Увеличить отступ" TRY "Разобрать код ветки ELSE" "Был отступ" ? ( "Перевести строку" ) // "Был отступ" ? FINALLY "Уменьшить отступ" END // TRY..FINALLY "Вывести отступ" 'end // else' "Вывести строку" "Перевести строку" FINALLY "Увеличить отступ" END FINALLY "Предыдущий Выходной файл" =: "Выходной файл" "Был отступ" := НЕТ "Предыдущий Выходной файл" := nil END // TRY..FINALLY ) // "Строка начинается с" '{' "Разобрать параметры тела IF" FINALLY "Обрабатываем тело END-IF" Если ( НЕ "Есть непустое условие" ) то ( "Вывести отступ" 'NOP' "Вывести строку" "Перевести строку" ) Если ( "Имя Файла для ELSE" НЕРАВНО '' ) то ( "Файл для ELSE" := nil "Файл для ELSE" := ( "Имя Файла для ELSE" file:OpenRead ) "Файл для ELSE" file:ReadLines ( W-STRING IN aString aString "Выходной файл" file:WriteWStrLn ) ) "Файл для ELSE" := nil Если ( "Имя Файла для ELSE" НЕРАВНО '' ) то ( "Имя Файла для ELSE" DeleteFile [ 'Не удалось удалить файл для ELSE: ' "Имя Файла для ELSE" ] strings:Cat ASSERTS ) END // TRY..FINALLY ; // "Обрабатываем IF" WordWorker "Расширенно" "Перевести строку" "Вывести отступ" 'bind ( ' "Вывести строку" "Перевести строку" "Увеличить отступ" "Вывести отступ" 'OBJECT VAR %S' "Вывести строку" "Перевести строку" WordToWork DO "Уменьшить отступ" "Перевести строку" "Вывести отступ" ') // bind' "Вывести строку" "Перевести строку" ; // "Расширенно" : "Обрабатываем IF с расширением" "Расширенно" "Обрабатываем IF" ; // "Обрабатываем IF с расширением" FORWARD "Обрабатываем тело конца цикла" FORWARD "Разобрать параметры тела цикла" : "Обрабатываем начало цикла" BOOLEAN VAR "Нужен счётчик цикла" "Нужен счётчик цикла" := НЕТ BOOLEAN VAR "Нужен выход из цикла" "Нужен выход из цикла" := НЕТ BOOLEAN VAR "Игнорировать первый элемент" "Игнорировать первый элемент" := НЕТ STRING VAR "Признак сортировки" "Признак сортировки" := '' BOOLEAN VAR "Обратный цикл" "Обратный цикл" := НЕТ BOOLEAN VAR "Игнорировать последний элемент" "Игнорировать последний элемент" := НЕТ BOOLEAN VAR "Удалять дубликаты" "Удалять дубликаты" := НЕТ : "Разбираем тело цикла" : "Разбираем параметры цикла" "Строка начинается с" '{' ? ( STRING VAR "Предыдущий аргумент цикла" "Предыдущий аргумент цикла" := "Аргумент цикла" "Аргумент цикла" := '' WString:++! "Текущая строка входного файла" // - отрезаем { ПОКА ( "Текущая строка входного файла" WString:Len !=0 ) BEGIN CHAR VAR "Текущий символ" WString:[]++! "Текущая строка входного файла" =: "Текущий символ" RULES ( "Текущий символ" РАВНО '}' ) BREAK ( "Текущий символ" РАВНО '%' ) ( WString:[]++! "Текущая строка входного файла" char:ToString =: "Аргумент цикла" // - отрезаем символ за % ) ( "Текущий символ" РАВНО 'W' ) ( "Нужен выход из цикла" := ДА ) ( "Текущий символ" РАВНО 'C' ) ( "Нужен счётчик цикла" := ДА ) ( "Текущий символ" РАВНО '+' ) ( "Игнорировать первый элемент" := ДА ) ( "Текущий символ" РАВНО '-' ) ( "Игнорировать последний элемент" := ДА ) ( "Текущий символ" РАВНО 'D' ) ( "Удалять дубликаты" := ДА ) ( "Текущий символ" РАВНО 'S' ) ( WString:[]++! "Текущая строка входного файла" char:ToString =: "Признак сортировки" // - отрезаем символ за S ) ( "Текущий символ" РАВНО 'r' ) ( "Обратный цикл" := ДА ) ; // RULES END Если ( "Аргумент цикла" РАВНО '' ) то ( "Аргумент цикла" := "Предыдущий аргумент цикла" ) ) // "Строка начинается с" '{' ; // "Разбираем параметры цикла" : "Разбираем параметры тела цикла" "Разобрать параметры тела цикла" ; // "Разбираем параметры тела цикла" STRING VAR "Имя Файла для ITEM-SEPARATOR" "Имя Файла для ITEM-SEPARATOR" := '' FILE VAR "Файл для ITEM-SEPARATOR" "Файл для ITEM-SEPARATOR" := nil TRY "Увеличить отступ" FILE VAR "Предыдущий Выходной файл" "Предыдущий Выходной файл" := nil "Предыдущий Выходной файл" := "Выходной файл" TRY "Строка начинается с" '{' ? ( Если ( 1 "Текущая строка входного файла" WString:[i] '}' ?!= ) то ( "Имя Файла для ITEM-SEPARATOR" := ( [ "Имя выходного файла" '.' "Количество открытых циклов" 1000 + //Random IntToStr '.itemseparator.txt' ] strings:Cat ) "Файл для ITEM-SEPARATOR" := ( "Имя Файла для ITEM-SEPARATOR" file:OpenWrite ) "Выходной файл" := "Файл для ITEM-SEPARATOR" "Был отступ" := НЕТ "Увеличить отступ" "Вывести отступ" 'if ( l_Counter >0 ) then ( ' "Вывести строку" WString:++! "Текущая строка входного файла" // - отрезаем { "Разобрать параметры 1-й части цикла" ')' "Вывести строку" "Перевести строку" "Уменьшить отступ" ) иначе ( 2 WString:+! "Текущая строка входного файла" // - отрезаем {} ) // 1 "Текущая строка входного файла" WString:[i] '}' ?!= ) // "Строка начинается с" '{' ? FINALLY "Предыдущий Выходной файл" =: "Выходной файл" "Был отступ" := НЕТ "Предыдущий Выходной файл" := nil "Файл для ITEM-SEPARATOR" := nil END "Аргумент цикла" := '' "Вывести отступ" 'if ' "Вывести строку" Если "Строка начинается с" '{' то ( Если ( 1 "Текущая строка входного файла" WString:[i] '}' ?!= ) то "Обрабатываем условие с отступом" иначе ( 2 WString:+! "Текущая строка входного файла" // - отрезаем {} 'true ' "Вывести строку" ) // 1 "Текущая строка входного файла" WString:[i] '}' ?!= ) // "Строка начинается с" '{' иначе ( 'true ' "Вывести строку" ) "Вывести отступ" 'then' "Вывести строку" "Перевести строку" "Вывести отступ" 'begin' "Вывести строку" "Перевести строку" "Увеличить отступ" "Разбираем параметры цикла" Если ( "Имя Файла для ITEM-SEPARATOR" НЕРАВНО '' ) то ( "Файл для ITEM-SEPARATOR" := nil "Файл для ITEM-SEPARATOR" := ( "Имя Файла для ITEM-SEPARATOR" file:OpenRead ) "Файл для ITEM-SEPARATOR" file:ReadLines ( W-STRING IN aString aString "Выходной файл" file:WriteWStrLn ) ) Если "Игнорировать первый элемент" то ( "Вывести отступ" 'if ( l_Counter >0 ) then' "Вывести строку" "Перевести строку" "Вывести отступ" 'begin' "Вывести строку" "Перевести строку" "Увеличить отступ" ) "Разбираем параметры тела цикла" Если "Игнорировать первый элемент" то ( "Уменьшить отступ" "Перевести строку" "Вывести отступ" 'end' "Вывести строку" ) "Уменьшить отступ" "Перевести строку" "Вывести отступ" ' ++! l_Counter' "Вывести строку" "Перевести строку" "Вывести отступ" 'end // if' "Вывести строку" "Перевести строку" Если ( "Нужен выход из цикла" И ( "Аргумент цикла" РАВНО '' ) ) то ( "Вывести отступ" 'else' "Вывести строку" "Перевести строку" "Вывести отступ" ' break' "Вывести строку" "Перевести строку" ) // "Нужен выход из цикла" FINALLY "Файл для ITEM-SEPARATOR" := nil Если ( "Имя Файла для ITEM-SEPARATOR" НЕРАВНО '' ) то ( "Имя Файла для ITEM-SEPARATOR" DeleteFile [ 'Не удалось удалить файл для ITEM-SEPARATOR: ' "Имя Файла для ITEM-SEPARATOR" ] strings:Cat ASSERTS ) END ; // "Разбираем тело цикла" STRING VAR "Предыдущий аргумент цикла" "Предыдущий аргумент цикла" := "Аргумент цикла" TRY "Аргумент цикла" := '' "Увеличить количество открытых циклов" TRY WString:++! "Текущая строка входного файла" // - отрезаем < Если "Накапливаемая строка пустая" то ( "Был отступ" ? "Перевести строку" "Вывести отступ" ) иначе ( "Сбросить накопленную строку и вывести отступ" ) STRING VAR "Имя Файла для тела цикла" "Имя Файла для тела цикла" := '' FILE VAR "Файл для тела цикла" "Файл для тела цикла" := nil "Имя Файла для тела цикла" := ( [ "Имя выходного файла" '.' "Количество открытых циклов" 1000 + //Random IntToStr '.for.txt' ] strings:Cat ) "Файл для тела цикла" := ( "Имя Файла для тела цикла" file:OpenWrite ) FILE VAR "Предыдущий Выходной файл" "Предыдущий Выходной файл" := nil "Предыдущий Выходной файл" := "Выходной файл" "Выходной файл" := "Файл для тела цикла" "Был отступ" := НЕТ TRY "Разбираем тело цикла" FINALLY "Предыдущий Выходной файл" =: "Выходной файл" "Был отступ" := НЕТ "Предыдущий Выходной файл" := nil 'INTEGER VAR l_Counter l_Counter := 0' "Вывести строку" "Перевести строку" "Уменьшить отступ" "Вывести отступ" Если ( "Аргумент цикла" РАВНО '' ) то ( 'while true' "Вывести строку" ) иначе ( 'for ' "Вывести строку" Если "Удалять дубликаты" то ( '"remove duplicates" ' "Вывести строку" ) Если "Обратный цикл" то ( 'downto ' "Вывести строку" ) '%S%' "Вывести строку" // "Кавычка" "Вывести строку" "Аргумент цикла" "Вывести строку" "Признак сортировки" "Вывести строку" Если "Игнорировать последний элемент" то ( '-' "Вывести строку" ) // "Кавычка" "Вывести строку" ) // - пишем "наш" FOR "Перевести строку" "Вывести отступ" 'begin' "Вывести строку" "Перевести строку" "Увеличить отступ" Если ( "Аргумент цикла" "НЕ РАВНО" '' ) то ( "Вывести отступ" 'OBJECT IN %' "Вывести строку" "Аргумент цикла" "Вывести строку" "Перевести строку" ) Если ( "Имя Файла для тела цикла" НЕРАВНО '' ) то ( "Файл для тела цикла" := nil "Файл для тела цикла" := ( "Имя Файла для тела цикла" file:OpenRead ) "Файл для тела цикла" file:ReadLines ( W-STRING IN aString aString "Выходной файл" file:WriteWStrLn ) ) "Файл для тела цикла" := nil Если ( "Имя Файла для тела цикла" НЕРАВНО '' ) то ( "Имя Файла для тела цикла" DeleteFile [ 'Не удалось удалить файл для тела цикла: ' "Имя Файла для тела цикла" ] strings:Cat ASSERTS ) END FINALLY "Обрабатываем тело конца цикла" END Если "Нужен счётчик цикла" то ( "Вывести отступ" 'l_Counter' "Вывести строку" "Перевести строку" ) FINALLY "Аргумент цикла" := "Предыдущий аргумент цикла" END ; // "Обрабатываем начало цикла" : "Обрабатываем начало цикла с расширением" "Расширенно" "Обрабатываем начало цикла" ; // "Обрабатываем начало цикла с расширением" : "Обрабатываем тело конца цикла" "Сбросить накопленную строку" "Уменьшить отступ" "Был отступ" ? "Перевести строку" "Вывести отступ" 'end // ' "Вывести строку" Если ( "Аргумент цикла" РАВНО '' ) то ( 'while' "Вывести строку" ) иначе ( 'for ' "Вывести строку" "Аргумент цикла" "Вывести строку" ) // - пишем "наш" END-FOR //"По любому пишем пробел, чтобы не слипалось с последующими строками" "Перевести строку" "Уменьшить количество открытых циклов" ; // "Обрабатываем тело конца цикла" BOOLEAN FUNCTION "Обрабатываем конец цикла" Если ( "Количество открытых циклов" =0 ) то ( // - видимо это какая-то другая скобка, например от inherited false =: Result ) иначе ( true =: Result WString:++! "Текущая строка входного файла" // - отрезаем > "Обрабатываем тело конца цикла" ) // "Количество открытых IF" =0 ; // "Обрабатываем конец цикла" : "Разобрать фактические параметры" STRING IN "Закрывающаяся скобка" BOOLEAN IN "Надо разбирать условие" BOOLEAN IN "Надо разбирать булевские значения" BOOLEAN IN "Надо разбирать цифры" BOOLEAN IN "Надо разбирать запятые" BOOLEAN IN "Надо считать скобки" BOOLEAN VAR "Первый проход разбора параметра" true =: "Первый проход разбора параметра" BOOLEAN VAR "Следующее значение переменной Первый проход разбора параметра" false =: "Следующее значение переменной Первый проход разбора параметра" BOOLEAN VAR "Встретилась закрывающаяся скобка" false =: "Встретилась закрывающаяся скобка" INTEGER VAR "Сохранённое количество открытых скобок параметров функции" "Количество открытых скобок параметров функции" =: "Сохранённое количество открытых скобок параметров функции" "Увеличить количество открытых скобок параметров функции" BOOLEAN VAR "Была открыта операторная скобка" false =: "Была открыта операторная скобка" : "Открыть операторную скобку" "Была открыта операторная скобка" ! ? ( "Перевести строку" "Вывести отступ" ' ( ' "Вывести строку" true =: "Была открыта операторная скобка" ) // "Была открыта операторная скобка" ; // "Открыть операторную скобку" : "Закрыть операторную скобку" "Была открыта операторная скобка" ? ( ' ) ' "Вывести строку" false =: "Была открыта операторная скобка" ) // "Была открыта операторная скобка" ; // "Закрыть операторную скобку" INTEGER VAR "Число дополнительных открытых скобок" 0 =: "Число дополнительных открытых скобок" BOOLEAN VAR "Двойная кавычка была открыта" false =: "Двойная кавычка была открыта" //'Двойная кавычка была открыта' log "Двойная кавычка была открыта" log BOOLEAN VAR "Надо считать кавычки" false =: "Надо считать кавычки" Если ( НЕ "Надо считать скобки" ) то ( ( "Закрывающаяся скобка" %== ')' ) ? ( true =: "Надо считать кавычки" //false =: "Надо считать кавычки" ) // "Закрывающаяся скобка" %== ')' ) ? ) // НЕ "Надо считать скобки" TRY ПОКА ( %! ( "Входной файл" file:EOF ) И // ( "Текущая строка входного файла" WString:Len !=0 ) И %! "Встретилась закрывающаяся скобка" ) BEGIN false =: "Следующее значение переменной Первый проход разбора параметра" //"Текущая строка входного файла" WString:[] log RULES "Строка начинается с" '(' ( Если "Надо считать скобки" то ( ( "Закрывающаяся скобка" %== ')' ) ? ( ++! "Число дополнительных открытых скобок" ) // ( "Закрывающаяся скобка" %== ')' ) ? ) // "Надо считать скобки" "Один проход разбора остатка без учёта его результата" ) // "Строка начинается с" '(' "Строка начинается с" "Знак процента" ( Если "Надо разбирать условие" то ( // - тут экранируем условие "Вывести отступ" '( ' "Вывести строку" "Обработать строку начинающуюся с % как начало цепочки" ') ' "Вывести строку" ) иначе "Обработать строку начинающуюся с % как начало цепочки" ) // "Строка начинается с" "Знак процента" "Строка начинается с" "Закрывающаяся скобка" ( BOOLEAN VAR "Скобка подходит" true =: "Скобка подходит" //'скобка' log //"Закрывающаяся скобка" log Если "Надо считать скобки" то ( ( "Число дополнительных открытых скобок" %== 0 ) =: "Скобка подходит" ) иначе ( //'Двойная кавычка была открыта' log "Двойная кавычка была открыта" log Если "Надо считать кавычки" то ( ( "Двойная кавычка была открыта" ! ) =: "Скобка подходит" ) иначе ( true =: "Скобка подходит" ) ) //'Скобка подходит' log //"Скобка подходит" log Если "Скобка подходит" то ( "Сбросить накопленную строку без перевода" WString:++! "Текущая строка входного файла" // - отрезаем скобку true =: "Встретилась закрывающаяся скобка" "Уменьшить количество открытых скобок параметров функции" ) иначе ( Если "Надо считать скобки" то ( --! "Число дополнительных открытых скобок" ) // "Надо считать скобки" "Один проход разбора остатка без учёта его результата" ) // "Скобка подходит" ) // "Строка начинается с" "Закрывающаяся скобка" ( "Надо разбирать запятые" И "Строка начинается с" ',,' ) ( : "Пустой параметр" "Вывести значение для пустой строки" ; // "Пустой параметр" "Сбросить накопленную строку без перевода" 2 WString:+! "Текущая строка входного файла" // - отрезаем ',,' //"Вывести пробел" '%, ' "Вывести строку" // - выводим такую хитрую запятую, которая будет склеивать все параметры перед ней в один "Пустой параметр" ' %, ' "Вывести строку" // - выводим такую хитрую запятую, которая будет склеивать все параметры перед ней в один true =: "Следующее значение переменной Первый проход разбора параметра" ) // "Строка начинается с" ',,' ( "Надо разбирать запятые" И "Строка начинается с" "Запятая" ) ( "Сбросить накопленную строку без перевода" WString:++! "Текущая строка входного файла" // - отрезаем запятую //"Вывести пробел" '%, ' "Вывести строку" // - выводим такую хитрую запятую, которая будет склеивать все параметры перед ней в один true =: "Следующее значение переменной Первый проход разбора параметра" ) // "Строка начинается с" "Запятая" "Строка начинается с" '""' ( 2 WString:+! "Текущая строка входного файла" // - отрезаем две двойных кавычки "Вывести значение для пустой строки" "Вывести пробел" ) // "Строка начинается с" '""' "Строка начинается с" '"true"' ( 6 WString:+! "Текущая строка входного файла" // - отрезаем "true" 'true ' "Вывести строку" ) // "Строка начинается с" '"true"' "Строка начинается с" '"false"' ( 7 WString:+! "Текущая строка входного файла" // - отрезаем "false" 'false ' "Вывести строку" ) // "Строка начинается с" '"false"' "Строка начинается с" "Двойная кавычка" ( //'got' log //'Двойная кавычка была открыта' log "Двойная кавычка была открыта" log "Двойная кавычка была открыта" ! =: "Двойная кавычка была открыта" //'Двойная кавычка была открыта' log "Двойная кавычка была открыта" log Если "Накапливаемая строка пустая" то ( WString:++! "Текущая строка входного файла" ) иначе ( CHAR VAR "Следующий символ" ( 1 "Текущая строка входного файла" WString:[i] ) =: "Следующий символ" Если ( ( "Следующий символ" %== "Закрывающаяся скобка" ) ИЛИ ( "Следующий символ" %== '=' ) ИЛИ ( "Надо разбирать условие" И ( ( "Следующий символ" %== '|' ) ИЛИ ( "Следующий символ" %== '&' ) ) ) ) то ( "Сбросить накопленную строку без перевода" WString:++! "Текущая строка входного файла" ) иначе ( //'got1' log "Один проход разбора остатка без учёта его результата" ) ) // "Накапливаемая строка пустая" ) // "Строка начинается с" "Двойная кавычка" "Строка начинается с" 'true' ( Если ( "Надо разбирать булевские значения" И "Накапливаемая строка пустая" ) то ( 4 WString:+! "Текущая строка входного файла" "Сбросить накопленную строку без перевода" "Вывести отступ" ' true ' "Вывести строку" ) иначе "Один проход разбора остатка без учёта его результата" ) // "Строка начинается с" 'true' "Строка начинается с" 'false' ( Если ( "Надо разбирать булевские значения" И "Накапливаемая строка пустая" ) то ( 5 WString:+! "Текущая строка входного файла" "Сбросить накопленную строку без перевода" "Вывести отступ" ' false ' "Вывести строку" ) иначе "Один проход разбора остатка без учёта его результата" ) // "Строка начинается с" 'false' "Строка начинается с" '!=' ( Если "Надо разбирать условие" то ( 2 WString:+! "Текущая строка входного файла" "Сбросить накопленную строку без перевода" "Вывести отступ" '%!= ' "Вывести строку" true =: "Следующее значение переменной Первый проход разбора параметра" ) иначе "Один проход разбора остатка без учёта его результата" ) // "Строка начинается с" '!=' "Строка начинается с" '=' ( //'got 3' log //"Закрывающаяся скобка" log Если "Надо разбирать условие" то ( //'got 4' log WString:++! "Текущая строка входного файла" "Сбросить накопленную строку без перевода" "Вывести отступ" '%== ' "Вывести строку" true =: "Следующее значение переменной Первый проход разбора параметра" ) иначе ( //'got 5' log //"Текущая строка входного файла" WString:[] log "Один проход разбора остатка без учёта его результата" //"Текущая строка входного файла" WString:[] log ) // "Надо разбирать условие" ) // "Строка начинается с" '=' "Строка начинается с" '&' ( Если "Надо разбирать условие" то ( WString:++! "Текущая строка входного файла" "Сбросить накопленную строку без перевода" "Вывести отступ" "Закрыть операторную скобку" 'AND ' "Вывести строку" "Открыть операторную скобку" true =: "Следующее значение переменной Первый проход разбора параметра" //"Перевести строку" ) иначе "Один проход разбора остатка без учёта его результата" ) // "Строка начинается с" '&' "Строка начинается с" '|' ( Если "Надо разбирать условие" то ( WString:++! "Текущая строка входного файла" "Сбросить накопленную строку без перевода" "Вывести отступ" "Закрыть операторную скобку" 'OR ' "Вывести строку" "Открыть операторную скобку" true =: "Следующее значение переменной Первый проход разбора параметра" //"Перевести строку" ) иначе "Один проход разбора остатка без учёта его результата" ) // "Строка начинается с" '|' "Строка начинается с" '[' ( // "Накапливаемая строка пустая" ! ? // ( 0 =: "Число дополнительных открытых скобок" ) "Один проход разбора остатка без учёта его результата" ) // "Строка начинается с" '[' "Строка начинается с" '<' ( // "Накапливаемая строка пустая" ! ? // ( 0 =: "Число дополнительных открытых скобок" ) "Один проход разбора остатка без учёта его результата" ) // "Строка начинается с" '[' "Строка начинается с" ']' ( "Закрыть операторную скобку" "Обрабатываем END-IF" ! ? "Один проход разбора остатка без учёта его результата" ) // "Строка начинается с" ']' "Строка начинается с" '>' ( "Закрыть операторную скобку" "Обрабатываем конец цикла" ! ? "Один проход разбора остатка без учёта его результата" ) // "Строка начинается с" '>' ( "Накапливаемая строка пустая" И "Строка начинается с" '+1' ) ( 2 WString:+! "Текущая строка входного файла" // - отрезаем +1 "Вывести отступ" Если "Первый проход разбора параметра" то ( '1 ' "Вывести строку" ) иначе ( 'integer:?++ ' "Вывести строку" ) // "Первый проход разбора параметра" ) // .. "Строка начинается с" '+1' ( "Накапливаемая строка пустая" И "Строка начинается с" '-1' ) ( 2 WString:+! "Текущая строка входного файла" // - отрезаем -1 "Вывести отступ" Если "Первый проход разбора параметра" то ( '-1 ' "Вывести строку" ) иначе ( 'integer:?-- ' "Вывести строку" ) // "Первый проход разбора параметра" ) // .. "Строка начинается с" '+1' ( "Накапливаемая строка пустая" И "Строка начинается с" '1+' ) ( 2 WString:+! "Текущая строка входного файла" // - отрезаем 1+ "Вывести отступ" '1 %integer:?+ ' "Вывести строку" ) // .. "Строка начинается с" '1+' ( "Надо разбирать цифры" И "Накапливаемая строка пустая" И ( "Строка пустая" ! ) И ( "Цифры" "Текущая строка входного файла" WString:[] WString:HasAnyOf ) //"Строка начинается с" '1' ) ( WString:[]++! "Текущая строка входного файла" // - отрезаем 1 "Вывести отступ" "Выходной файл" file:WriteChar //'1 ' "Вывести строку" ПОКА ( ( "Строка пустая" ! ) И ( "Цифры" "Текущая строка входного файла" WString:[] WString:HasAnyOf ) ) BEGIN WString:[]++! "Текущая строка входного файла" // - отрезаем 1 "Выходной файл" file:WriteChar END "Вывести пробел" ) // .. "Строка начинается с" '1' DEFAULT "Один проход разбора остатка без учёта его результата" ; // RULES "Следующее значение переменной Первый проход разбора параметра" =: "Первый проход разбора параметра" ( "Встретилась закрывающаяся скобка" ! ) ? ( BOOLEAN VAR "Встретилась значащая строка" false =: "Встретилась значащая строка" ПОКА ( %! ( "Входной файл" file:EOF ) И %! "Встретилась значащая строка" И ( "Строка пустая" ) //( "Текущая строка входного файла" WString:Len =0 ) ) BEGIN "Был признак переноса" := НЕТ "Входной файл" file:ReadWStrLn =: "Текущая строка входного файла" RULES "Обрабатываем незначащие строки с переводом строки перед ними" ( "Текущая строка входного файла" WString:Len WString:+! "Текущая строка входного файла" // - сигнализируем остальным, что строка типа закончилась //false =: "Встретилась значащая строка" ) // "Обрабатываем незначащие строки с переводом строки перед ними" "Строка начинается с" "Табуляция" ( "Вывести строку как комментарий. Чтобы в конечном файле было с чем сравнивать" WString:++! "Текущая строка входного файла" true =: "Встретилась значащая строка" ) // "Строка начинается с" "Табуляция" DEFAULT ( //EXIT // - это можно раскомментировать для целей отладки false [ 'Строка "' "Текущая строка входного файла" WString:ToString '" должна начинаться с табуляции' ] strings:Cat ASSERTS ) // DEFAULT ; // RULES END // ( "Строка пустая" ) ? ( ) // ( "Встретилась закрывающаяся скобка" ! ) ? ( END // "Текущая строка входного файла" WString:Len !=0 // - типа копируем параметры, может быть понадобится и их синтаксический разбор FINALLY "Закрыть операторную скобку" ( "Количество открытых скобок параметров функции" %!= "Сохранённое количество открытых скобок параметров функции" ) ? ( //EXIT false [ 'Не дождались закрытия скобки: ' "Закрывающаяся скобка" ' Текущая строка: ' "Текущая строка входного файла" WString:ToString ] strings:Cat ASSERTS ) END // TRY..FINALLY ; // "Разобрать фактические параметры" : "Разобрать фактические параметры функции" BOOLEAN IN "Надо считать скобки" //'Разобрать фактические параметры функции in' log "Закрывающаяся скобка" false false true true "Надо считать скобки" "Разобрать фактические параметры" //'Разобрать фактические параметры функции out' log ; // "Разобрать фактические параметры функции" : "Разобрать фактические параметры функции, без разбора цифр" BOOLEAN IN "Надо считать скобки" //'Разобрать фактические параметры функции, без разбора цифр in' log "Закрывающаяся скобка" false false false true "Надо считать скобки" "Разобрать фактические параметры" //'Разобрать фактические параметры функции, без разбора цифр out' log ; // "Разобрать фактические параметры функции, без разбора цифр" : "Разобрать параметры 1-й части цикла" '}' false false false false false "Разобрать фактические параметры" ; // "Разобрать параметры 1-й части цикла" // : "Разобрать параметры 3-й части цикла" // '}' false false false false false "Разобрать фактические параметры" // ; // "Разобрать параметры 3-й части цикла" : "Разобрать фактические параметры условия" //'Разобрать фактические параметры условия in' log '}' true true true false false "Разобрать фактические параметры" //'Разобрать фактические параметры условия out' log ; // "Разобрать фактические параметры условия" : "Разобрать имя переменной" //'Разобрать имя переменной in' log '}' false true false false false "Разобрать фактические параметры" //'Разобрать имя переменной out' log ; // "Разобрать имя переменной" : "Разобрать код ветки ELSE" '}' false true true false false "Разобрать фактические параметры" ; // "Разобрать код ветки ELSE" : "Разобрать параметры тела цикла" '>' false true true false false "Разобрать фактические параметры" ; // "Разобрать параметры тела цикла" : "Разобрать параметры тела IF" ']' false true true false false "Разобрать фактические параметры" ; // "Разобрать параметры тела IF" : "Разобрать сигнатуру функции" BOOLEAN VAR "Надо разбирать цифры" W-STRING VAR "Имя функции" "Открывающаяся скобка" WString:SplitTo! "Текущая строка входного файла" =: "Имя функции" "Имя функции" WString:IsNil ! 'Видимо не нашлась скобка, видимо она на другой строке' ASSERTS ( ( "Имя функции" %!= 'find_element' ) И ( "Имя функции" %!= 'add_to_list' ) И ( "Имя функции" %!= 'exists_in_list' ) И ( "Имя функции" %!= 'consist_of' ) И ( "Имя функции" %!= 'clear_list' ) ) =: "Надо разбирать цифры" BOOLEAN VAR "Надо считать скобки" ( ( "Имя функции" %== 'add_operation' ) ИЛИ ( "Имя функции" %== 'set_uc_content' ) ИЛИ ( "Имя функции" %== 'set_documentation' ) ИЛИ ( "Имя функции" %== 'add_attribute' ) ) =: "Надо считать скобки" "Имя функции" "Выходной файл" file:WriteWStr // - пишем имя функции "Вывести пробел" '%(' "Вывести строку" "Вывести пробел" Если "Надо разбирать цифры" то ( "Надо считать скобки" "Разобрать фактические параметры функции" ) иначе ( "Надо считать скобки" "Разобрать фактические параметры функции, без разбора цифр" ) // "Надо разбирать цифры" //"Вывести пробел" ')%' "Вывести строку" // - выводим хитрые скобки, которые умею работать вместе с %, ; // "Разобрать сигнатуру функции" : "Разобрать вызов унаследованной функции по имени родительского стереотипа" ']' WString:SplitTo! "Текущая строка входного файла" DUP WString:IsNil ! 'Видимо не нашлась скобка, видимо она на другой строке' ASSERTS "Вывести кавычку" STRING W-STRING VAR "Имя родительского стереотипа" =: "Имя родительского стереотипа" "Имя родительского стереотипа" WString:IsNil ! 'Имя родительского стереотипа не может быть пустым' ASSERTS "Разделитель частей стереотипа" WString:SplitTo! "Имя родительского стереотипа" STRING W-STRING VAR "Класс родительского стереотипа" "Имя родительского стереотипа" =: "Класс родительского стереотипа" =: "Имя родительского стереотипа" "Имя родительского стереотипа" WString:IsNil ! 'Имя родительского стереотипа не может быть пустым' ASSERTS Если ( ':' "Класс родительского стереотипа" WString:HasAnyOf ) то ( //( false 'С подстереотипами надо разбираться отдельно' ASSERTS ) // - пока их обратно склеиваем "Имя родительского стереотипа" "Выходной файл" file:WriteWStr "Разделитель частей стереотипа" "Вывести строку" "Разделитель частей стереотипа" string:SplitTo! "Класс родительского стереотипа" DROP // =: "Класс родительского стереотипа" "Класс родительского стереотипа" "Выходной файл" file:WriteWStr ) иначе ( "Имя родительского стереотипа" "Выходной файл" file:WriteWStr ) // - пишем имя родительского стереотипа "Вывести кавычку" "Вывести пробел" Если ( НЕ "Строка начинается с" 'f_' ) то ( : "Вывести спецзначение для одноимённой функции" 'SAME_NAME %( )%' "Вывести строку" ; // "Вывести спецзначение для одноимённой функции" RULES "Строка равна" '\' ( WString:++! "Текущая строка входного файла" // - отрезаем \ "Вывести спецзначение для одноимённой функции" ) // "Строка равна" '\' "Строка пустая" "Вывести спецзначение для одноимённой функции" "Строка начинается с" ']' //"Строка равна" ']' // - это наверное чужой закрывающийся IF "Вывести спецзначение для одноимённой функции" DEFAULT ( false [ 'В строке ' "Текущая строка входного файла" WString:ToString ' ожидается f_' ] strings:Cat ASSERTS ) // DEFAULT ; // RULES ) иначе ( 2 WString:+! "Текущая строка входного файла" // - отрезаем f_ "Разобрать сигнатуру функции" ) // НЕ "Строка начинается с" 'f_' "Перевести строку" ; // "Разобрать вызов унаследованной функции по имени родительского стереотипа" FORWARD "Обработать строку начинающуюся с % без отрезания %" BOOLEAN FUNCTION "Строка начинается с правильной буквы аргумента" Если ( "Строка начинается с" 'S' ИЛИ "Строка начинается с" 'D' ИЛИ "Строка начинается с" 'd' ИЛИ "Строка начинается с" 'C' ИЛИ "Строка начинается с" 'N' ИЛИ "Строка начинается с" 'U' ИЛИ "Строка начинается с" 'K' ИЛИ "Строка начинается с" 'I' ИЛИ "Строка начинается с" 'x' ИЛИ "Строка начинается с" 'n' ИЛИ "Строка начинается с" 'V' ИЛИ "Строка начинается с" 'F' ИЛИ "Строка начинается с" 'O' ИЛИ "Строка начинается с" 'A' ИЛИ "Строка начинается с" 'R' ИЛИ "Строка начинается с" 'G' ИЛИ "Строка начинается с" 'M' ИЛИ "Строка начинается с" 'o' ИЛИ "Строка начинается с" 'L' ИЛИ "Строка начинается с" 'Z' ИЛИ "Строка начинается с" 'a' ИЛИ "Строка начинается с" 'l' ИЛИ "Строка начинается с" 'f' ИЛИ "Строка начинается с" 'r' ИЛИ "Строка начинается с" 't' ИЛИ "Строка начинается с" 'e' ИЛИ "Строка начинается с" '+' ИЛИ "Строка начинается с" '?' ИЛИ "Строка начинается с" 'W' ИЛИ "Строка начинается с" 'b' ИЛИ "Строка начинается с" 'Y' ИЛИ "Строка начинается с" 's' ИЛИ "Строка начинается с" 'P' ИЛИ "Строка начинается с" 'p' ИЛИ "Строка начинается с" 'X' ИЛИ // - на самом деле это надо превратить во что-то вроде ==> execute_current_generator "Строка начинается с" 'T' ) то ( true =: Result ) иначе ( false =: Result ) ; // "Строка начинается с правильной буквы аргумента" : "Разобрать UP" // - тут обрабатываем user property WString:++! "Текущая строка входного файла" // - отрезаем { '}' WString:SplitTo! "Текущая строка входного файла" W-STRING VAR "Имя UP" =: "Имя UP" "Имя UP" WString:IsNil ! 'Видимо не нашлась скобка, видимо она на другой строке' ASSERTS Если ( "Имя UP" "начинается с" '!' ) то ( ' get_up_def ( ' "Вывести строку" WString:++! "Имя UP" // - отрезаем ! ) иначе ( ' get_up ( ' "Вывести строку" ) "Вывести кавычку" "Имя UP" "Выходной файл" file:WriteWStr // - пишем имя user property "Вывести кавычку" "Вывести пробел" ')' "Вывести строку" ; // "Разобрать UP" : "Разобрать переменную" BOOLEAN IN aGlobal Если aGlobal то ( '( get_global_var ( ' "Вывести строку" ) иначе ( '( get_object_var ( ' "Вывести строку" ) "Разобрать имя переменной" //"Текущая строка входного файла" WString:[] log BOOLEAN VAR "IF с расширением" "IF с расширением" := НЕТ BOOLEAN VAR "Цикл с расширением" "Цикл с расширением" := НЕТ RULES "Строка начинается с" "Знак процента" ( ') ' "Вывести строку" "Обработать строку начинающуюся с % как вызов метода объекта" ') ' "Вывести строку" EXIT ) // "Строка начинается с" "Знак процента" "Строка начинается с" ',' NOP "Строка начинается с" '(' NOP "Строка начинается с" ')' NOP "Строка начинается с" '<' ( NOP // - наверное это цикл с расширением для переменной "Цикл с расширением" := ДА ) "Строка начинается с" '=' NOP "Строка начинается с" '"' NOP "Строка начинается с" '{' ( ')' "Вывести строку" "Разобрать UP" ' ) ' "Вывести строку" EXIT //NOP ) // "Строка начинается с" '{' "Строка начинается с" '}' NOP "Строка начинается с" '[' ( NOP // - наверное это IF с расширением для переменной "IF с расширением" := ДА ) "Строка начинается с" ']' NOP // ( // "Обрабатываем END-IF" ! ? // "Один проход разбора остатка без учёта его результата" // ) // "Строка начинается с" ']' "Строка начинается с" '>' NOP // ( // "Обрабатываем конец цикла" ! ? // "Один проход разбора остатка без учёта его результата" // ) // "Строка начинается с" '>' "Строка начинается с правильной буквы аргумента" ( // - тут пишем квалификатор того, чего хотят от переменной WString:[]++! "Текущая строка входного файла" ') ' "Вывести строку" '|' "Вывести строку" "Выходной файл" file:WriteChar "Вывести пробел" ') ' "Вывести строку" EXIT ) // DEFAULT DEFAULT ( // // - тут пишем квалификатор того, чего хотят от переменной // WString:[]++! "Текущая строка входного файла" // "Вывести кавычку" // "Выходной файл" file:WriteChar // "Вывести кавычку" // "Вывести пробел" ) // DEFAULT ; // RULES ') ) ' "Вывести строку" Если "IF с расширением" то "Обрабатываем IF с расширением" иначе Если "Цикл с расширением" то "Обрабатываем начало цикла с расширением" ; //"Разобрать переменную" : "Разобрать глобальную переменную" true "Разобрать переменную" ; // "Разобрать глобальную переменную" : "Разобрать переменную объекта" false "Разобрать переменную" ; // "Разобрать переменную объекта" : "Обработать строку начинающуюся с % без отрезания %" BOOLEAN IN aGlobal "Сбросить накопленную строку и вывести отступ" RULES "Строка начинается с" 'S%[inherited]f_' ( DROP // - убираем со стека % 15 WString:+! "Текущая строка входного файла" // - отрезаем S%[inherited]f_ 'call-inherited ' "Вывести строку" "Разобрать сигнатуру функции" "Перевести строку" ) // "Строка начинается с" 'S%[inherited]' "Строка начинается с" 'S%[inherited]' ( DROP // - убираем со стека % 13 WString:+! "Текущая строка входного файла" // - отрезаем S%[inherited] 'inherited' "Вывести строку" "Перевести строку" ) // "Строка начинается с" 'S%[inherited]' "Строка начинается с" 'S#[inherited]' ( DROP // - убираем со стека % 13 WString:+! "Текущая строка входного файла" // - отрезаем S#[inherited] '?inherited' "Вывести строку" "Перевести строку" ) // "Строка начинается с" 'S#[inherited]' "Строка начинается с" 'S%[' ( // - это вызов унаследованной функции по имени DROP // - убираем со стека % 3 WString:+! "Текущая строка входного файла" // - отрезаем S%[ 'call-inherited::' "Вывести строку" "Вывести пробел" "Разобрать вызов унаследованной функции по имени родительского стереотипа" ) // "Строка начинается с" 'S%[' "Строка начинается с" 'S#[' ( // - это вызов унаследованной функции по имени DROP // - убираем со стека % 3 WString:+! "Текущая строка входного файла" // - отрезаем S#[ '?call-inherited::' "Вывести строку" "Вывести пробел" "Разобрать вызов унаследованной функции по имени родительского стереотипа" ) // "Строка начинается с" 'S#[' "Строка начинается с" 'f_' ( // - это вызов глобальной функции DROP // - убираем со стека % 2 WString:+! "Текущая строка входного файла" // - отрезаем 'f_' Если aGlobal то ( '[%f] ' "Вывести строку" ) иначе ( '%f ' "Вывести строку" ) "Разобрать сигнатуру функции" "По любому пишем пробел, чтобы не слипалось с последующими строками" ) // "Строка начинается с" 'f_' "Строка начинается с" 't_' ( // - это вызов глобального трансформатора DROP // - убираем со стека % 2 WString:+! "Текущая строка входного файла" // - отрезаем 't_' Если aGlobal то ( '[%t] ' "Вывести строку" ) иначе ( '%t ' "Вывести строку" ) "Разобрать сигнатуру функции" "По любому пишем пробел, чтобы не слипалось с последующими строками" ) // "Строка начинается с" 't_' "Строка начинается с" '{' ( // - это глобальная переменная DROP // - убираем со стека % WString:++! "Текущая строка входного файла" // - отрезаем { "Разобрать глобальную переменную" ) // "Строка начинается с" '{' DEFAULT ( Если aGlobal то ( "Выходной файл" file:WriteChar // - пишем собственно % ) иначе ( DROP // - убираем со стека % ' ->' "Вывести строку" // - отделяем поля-подстановки, от реальных вызовов методов на стереотипах // т.е. %S %P => %S %P, %S%P => %S ->P и т.п. // т.к. для "моего мира" - они по сути - РАЗНЫЕ ) RULES ( "Количество открытых скобок параметров функции" >0 И "Строка начинается с" "Закрывающаяся скобка" ) ( false 'После % закрывающаяся скобка недопустима' ASSERTS // "Ничего не делаем" // - чтобы отдать скобку тому, кто её ждёт ) // "Строка начинается с" "Закрывающаяся скобка" .. DEFAULT ( CHAR VAR "Символ после %" : "Пишем символ после %" WString:[]++! "Текущая строка входного файла" =: "Символ после %" // - берём символ после % STRING VAR "Предположительный аргумент цикла" "Предположительный аргумент цикла" := ( "Символ после %" char:ToString ) Если ( ( "Предположительный аргумент цикла" "НЕ РАВНО" 'S' ) И ( "Предположительный аргумент цикла" "НЕ РАВНО" 'X' ) И ( "Предположительный аргумент цикла" "НЕ РАВНО" 'U' ) И ( "Предположительный аргумент цикла" "НЕ РАВНО" '1' ) И ( "Предположительный аргумент цикла" "НЕ РАВНО" '2' ) И ( "Предположительный аргумент цикла" "НЕ РАВНО" 'M' ) И ( "Предположительный аргумент цикла" "НЕ РАВНО" 'B' ) И ( "Предположительный аргумент цикла" "НЕ РАВНО" 'T' ) И ( "Предположительный аргумент цикла" "НЕ РАВНО" 'V' ) ) то ( Если ( "Аргумент цикла" РАВНО '' ) то ( "Аргумент цикла" := "Предположительный аргумент цикла" ) ) "Символ после %" "Выходной файл" file:WriteChar ; // "Пишем символ после %" "Пишем символ после %" RULES "Строка начинается с" "Знак процента" ( WString:[]++! "Текущая строка входного файла" // - отрезаем % RULES "Строка начинается с" 'f_' ( // - это вызов функции объекта DROP 2 WString:+! "Текущая строка входного файла" // - отрезаем 'f_' ' %f ' "Вывести строку" "Разобрать сигнатуру функции" ) // "Строка начинается с" 'f_' "Строка начинается с" 't_' ( // - это вызов функции объекта DROP 2 WString:+! "Текущая строка входного файла" // - отрезаем 'f_' ' %t ' "Вывести строку" "Разобрать сигнатуру функции" ) // "Строка начинается с" 't_' "Строка начинается с" '{' ( // - это переменная объекта DROP WString:++! "Текущая строка входного файла" // - отрезаем { "Вывести пробел" "Разобрать переменную объекта" ) // "Строка начинается с" '{' DEFAULT ( //DROP // - на самом деле нам этот символ там как раз нужен false "Обработать строку начинающуюся с % без отрезания %" //"Выходной файл" file:WriteChar // - пишем собственно % ) // ; // RULES ) // "Строка начинается с" "Знак процента" "Строка начинается с" '#' ( WString:[]++! "Текущая строка входного файла" // - отрезаем # RULES "Строка начинается с" 'f_' ( // - это вызов функции объекта, которой может не быть DROP 2 WString:+! "Текущая строка входного файла" // - отрезаем 'f_' ' %?f ' "Вывести строку" "Разобрать сигнатуру функции" ) // "Строка начинается с" 'f_' "Строка начинается с" 't_' ( // - это вызов функции объекта, которой может не быть DROP 2 WString:+! "Текущая строка входного файла" // - отрезаем 't_' ' %?t ' "Вывести строку" "Разобрать сигнатуру функции" ) // "Строка начинается с" 't_' DEFAULT ( "Выходной файл" file:WriteChar // - пишем собственно # ) // ; // RULES ) // "Строка начинается с" '#' "Строка начинается с" '[' ( // - это IF с "расширением" Если ( "Символ после %" РАВНО 'U' ) то ( // - это пользовательская секция 'sersection (' "Вывести строку" "Перевести строку" WString:++! "Текущая строка входного файла" // - отрезаем [ "Строка начинается с" '{' ? ( WString:++! "Текущая строка входного файла" // - отрезаем { "Увеличить отступ" "Разобрать код ветки ELSE" "Уменьшить отступ" //"Разобрать параметры 1-й части цикла" ) "Перевести строку" "Вывести отступ" ')' "Вывести строку" "Перевести строку" "Вывести отступ" '(' "Вывести строку" "Перевести строку" "Увеличить отступ" "Разобрать параметры тела IF" "Перевести строку" "Уменьшить отступ" "Вывести отступ" ') // Usersection' "Вывести строку" "Перевести строку" ) иначе "Обрабатываем IF с расширением" ) "Строка начинается с" '<' // - это цикл с "расширением" "Обрабатываем начало цикла с расширением" "Строка начинается с" '{' "Разобрать UP" "Строка начинается с правильной буквы аргумента" ( WString:[]++! "Текущая строка входного файла" // - отрезаем ВТОРУЮ БУКВУ после %БУКВА ' |' "Вывести строку" "Выходной файл" file:WriteChar // - пишем эту букву в файл ) // "Строка начинается с правильной буквы аргумента" ; // RULES // - тут разбираем строку после %БУКВА ) // DEFAULT ; // RULES "По любому пишем пробел, чтобы не слипалось с последующими строками" ) // DEFAULT ; // RULES ; // "Обработать строку начинающуюся с % без отрезания %" : "Обработать строку начинающуюся с %" BOOLEAN IN aGlobal WString:[]++! "Текущая строка входного файла" // - отрезаем % aGlobal "Обработать строку начинающуюся с % без отрезания %" ; // "Обработать строку начинающуюся с %" : "Обработать строку начинающуюся с % как начало цепочки" true "Обработать строку начинающуюся с %" ; // "Обработать строку начинающуюся с % как начало цепочки" : "Обработать строку начинающуюся с % как вызов метода объекта" false "Обработать строку начинающуюся с %" ; // "Обработать строку начинающуюся с % как вызов метода объекта" : "Обрабатываем тело END-IF" "Сбросить накопленную строку" "Уменьшить отступ" "Был отступ" ? "Перевести строку" "Вывести отступ" 'end // if' "Вывести строку" // - пишем "наш" END-IF //"По любому пишем пробел, чтобы не слипалось с последующими строками" "Перевести строку" "Уменьшить количество открытых IF" ; // "Обрабатываем тело END-IF" BOOLEAN FUNCTION "Обрабатываем END-IF" Если ( "Количество открытых IF" =0 ) то ( // - видимо это какая-то другая скобка, например от inherited false =: Result ) иначе ( true =: Result WString:++! "Текущая строка входного файла" // - отрезаем ] "Обрабатываем тело END-IF" ) // "Количество открытых IF" =0 ; // "Обрабатываем END-IF" BOOLEAN FUNCTION "Один проход разбора остатка" : "Выводим следующий символ после \" WString:++! "Текущая строка входного файла" // - отрезаем \ Если ( "Текущая строка входного файла" WString:Len !=0 ) то ( RULES "Строка начинается с" 'n' ( WString:++! "Текущая строка входного файла" '#13#10' "Добавить спецстроку к накапливаемой строке" ) "Строка начинается с" 't' ( WString:++! "Текущая строка входного файла" '#9' "Добавить спецстроку к накапливаемой строке" ) DEFAULT "Выводим следующий символ как есть" ; // RULES ) // "Текущая строка входного файла" WString:Len !=0 ? иначе ( "Был признак переноса" := ДА ) ; // "Выводим следующий символ после \" : "Вывести булевское значение без установки результата" IN aStr "Сбросить накопленную строку" "Вывести отступ" Если ( aStr IsWString ) то ( aStr "Выходной файл" file:WriteWStr ) иначе ( aStr "Выходной файл" file:WriteStr ) // aStr IsWString ; // "Вывести булевское значение без установки результата" : "Вывести булевское значение" "Текущая строка входного файла" "Вывести булевское значение без установки результата" "Перевести строку" true =: Result ; // "Вывести булевское значение" false =: Result RULES "Строка пустая" ( Если ( НЕ "Был признак переноса" ) то ( '#13#10' "Добавить спецстроку к накапливаемой строке" ) "Сбросить накопленную строку" "Вывести строку как есть" true =: Result ) // "Строка пустая" ( "Строка равна" 'true' ИЛИ "Строка равна" 'false' ) ( "Вывести булевское значение" "Текущая строка входного файла" WString:Len WString:+! "Текущая строка входного файла" // - сигнализируем остальным, что строка закончилась ) // "Строка равна" 'true' ИЛИ.. ( "Строка равна" 'true\' ИЛИ "Строка равна" 'false\' ) ( WString:--Len! "Текущая строка входного файла" "Вывести булевское значение" "Текущая строка входного файла" WString:Len WString:+! "Текущая строка входного файла" // - сигнализируем остальным, что строка закончилась ) // "Строка равна" 'true\' ИЛИ .. "Строка начинается с" 'true' ( Если "Накапливаемая строка пустая" то ( //"Сбросить накопленную строку без перевода" 'true' "Вывести булевское значение без установки результата" "Вывести пробел" 4 WString:+! "Текущая строка входного файла" //"Перевести строку" ) иначе ( "Выводим следующий символ как есть" ) // "Накапливаемая строка пустая" ) // "Строка начинается с" 'true' "Строка начинается с" 'false' ( Если "Накапливаемая строка пустая" то ( //"Сбросить накопленную строку без перевода" 'false' "Вывести булевское значение без установки результата" "Вывести пробел" 5 WString:+! "Текущая строка входного файла" //"Перевести строку" ) иначе ( "Выводим следующий символ как есть" ) // "Накапливаемая строка пустая" ) // "Строка начинается с" 'false' ( "Спецсимволы" "Текущая строка входного файла" WString:HasAnyOf ! ) ( //'got 100' log "Вывести отступ" "Открыть кавычку, если не было" "Вывести исходную строку" "Закрыть кавычку, если была" "Перевести строку" true =: "Накапливаемая строка пустая" true =: Result "Текущая строка входного файла" WString:Len WString:+! "Текущая строка входного файла" // - сигнализируем остальным, что строка закончилась ) // ( "Спецсимволы" "Текущая строка входного файла" WString:HasAnyOf ! ) "Строка начинается с" '\' "Выводим следующий символ после \" "Строка начинается с" "Знак процента" "Обработать строку начинающуюся с % как начало цепочки" "Строка начинается с" '[' "Обрабатываем IF" "Строка начинается с" '<' "Обрабатываем начало цикла" "Строка начинается с" ']' ( "Обрабатываем END-IF" ! ? "Выводим следующий символ как есть" ) "Строка начинается с" '>' ( "Обрабатываем конец цикла" ! ? "Выводим следующий символ как есть" ) "Строка начинается с" '#' ( WString:++! "Текущая строка входного файла" // - отрезаем '#' "Сбросить накопленную строку" "Вывести отступ" 'out_indent ' "Вывести строку" ) // "Строка начинается с" '#' /*{ "Строка начинается с" '=' ( Если ( "Количество открытых скобок параметров функции" =0 ) то ( "Выводим следующий символ как есть" ) иначе ( Если ( "Накапливаемая строка пустая" ! ) то ( "Выводим следующий символ как есть" ) иначе ( WString:++! "Текущая строка входного файла" '%== ' "Вывести строку" ) ) ) // "Строка начинается с" '=' }*/ DEFAULT ( //"Текущая строка входного файла" WString:[] log "Выводим следующий символ как есть" //"Текущая строка входного файла" WString:[] log ) // DEFAULT ; // RULES ; // "Один проход разбора остатка" : "Разбираем остаток строки кода шаблона" BOOLEAN VAR l_Done false =: l_Done ПОКА ( "Текущая строка входного файла" WString:Len !=0 И %! l_Done ) BEGIN "Один проход разбора остатка" =: l_Done END // @ ( "Текущая строка входного файла" WString:Len !=0 ) ; // "Разбираем остаток строки кода шаблона" WString:++! "Текущая строка входного файла" // - отрезаем табуляцию "Увеличить отступ" TRY "Разбираем остаток строки кода шаблона" "Сбросить накопленную строку" FINALLY "Уменьшить отступ" END // TRY..FINALLY ; // "Разбираем код функции шаблона с начала строки" : "Обработать включение файла" STRING VAR "Новый файл" 2 WString:+! "Текущая строка входного файла" // - отрезаем '# ' "Текущая строка входного файла" WString:ToString =: "Новый файл" "Новый файл" log "Новый файл" '/' '\' string:Replace =: "Новый файл" "Новый файл" log WORDWORKER "Имя файла начинается с" WordToWork DO "Новый файл" StartsStr ; // "начинается с" : "Обработать новый файл" STRING VAR "Новый файл для включения" : "Обработать включение файла" "Новый файл" log "Закрыть все скобки" 'USES' "Вывести строку с переводом строки" "Пробел" "Вывести строку" "Вывести кавычку" "Новый файл для включения" "Вывести строку" "Кавычка" "Вывести строку с переводом строки" ';' "Вывести строку с переводом строки" TRY "Новый файл" "Обработать файл" EXCEPT 'Ошибка в ' "Новый файл" Cat log current:exception:ClassName log current:exception:Message log // - чтобы продолжить обработку файла END // TRY..EXCEPT ; // "Обработать включение файла" : "Обрабатываем файл в той же директории" 2 string:+! "Новый файл" // - отрезаем '.\' "Новый файл" log [ "Путь к выходному файлу" "Новый файл" '.script' ] strings:Cat =: "Новый файл для включения" [ "Путь к входному файлу" "Новый файл" ] strings:Cat =: "Новый файл" "Обработать включение файла" ; // "Обрабатываем файл в той же директории" : "Обработать файл в родительской директории" STRING VAR "Путь к выходному файлу на уровень выше" "Путь к выходному файлу" =: "Путь к выходному файлу на уровень выше" STRING VAR "Путь к входному файлу на уровень выше" "Путь к входному файлу" =: "Путь к входному файлу на уровень выше" '\' "Путь к выходному файлу на уровень выше" EndsStr ? ( string:--Len! "Путь к выходному файлу на уровень выше" ) '\' "Путь к входному файлу на уровень выше" EndsStr ? ( string:--Len! "Путь к входному файлу на уровень выше" ) "Новый файл" log '\' string:RSplitTo! "Путь к выходному файлу на уровень выше" DROP '\' string:RSplitTo! "Путь к входному файлу на уровень выше" DROP [ "Путь к выходному файлу на уровень выше" "Новый файл" '.script' ] strings:Cat =: "Новый файл для включения" [ "Путь к входному файлу на уровень выше" "Новый файл" ] strings:Cat =: "Новый файл" "Обработать включение файла" ; // "Обработать файл в родительской директории" RULES "Имя файла начинается с" '.\..\' ( 4 string:+! "Новый файл" // - отрезаем '.\..' "Обработать файл в родительской директории" ) "Имя файла начинается с" '..\' ( 2 string:+! "Новый файл" // - отрезаем '..' "Обработать файл в родительской директории" ) "Имя файла начинается с" '.\' "Обрабатываем файл в той же директории" //DEFAULT // "Обработать включение файла" ; // RULES ; // "Обработать новый файл" "Обработать новый файл" ; // "Обработать включение файла" : "Обработать вызов другого генератора" 2 WString:+! "Текущая строка входного файла" // - отрезаем '= ' '%call-other-gen ( ' "Вывести строку" STRING W-STRING VAR "Имя стереотипа" "Текущая строка входного файла" =: "Имя стереотипа" "Разделитель частей стереотипа" WString:SplitTo! "Имя стереотипа" "Вывести кавычку" "Выходной файл" file:WriteWStr "Вывести кавычку" "Разделитель частей стереотипа" string:SplitTo! "Имя стереотипа" STRING VAR "Имя под-стереотипа" Если ( "Имя стереотипа" string:Len =0 ) то ( =: "Имя стереотипа" ';' string:SplitTo! "Имя стереотипа" DROP "Пустая строка" =: "Имя под-стереотипа" ) иначе ( DROP ';' string:SplitTo! "Имя стереотипа" =: "Имя под-стереотипа" ) "Имя под-стереотипа" string:Len !=0 ? ( "Вывести пробел" "Вывести кавычку" "Имя под-стереотипа" "Вывести строку" "Вывести кавычку" ) // "Имя под-стереотипа" string:Len !=0 ? "Имя стереотипа" string:Len !=0 ? ( "Вывести пробел" "Вывести кавычку" "Имя стереотипа" "Вывести строку" "Вывести кавычку" ) // "Имя стереотипа" WString:IsNil ! ? ' )' "Вывести строку" "Перевести строку" ; // "Обработать вызов другого генератора" : "Обработать правило трансформатора" 2 WString:+! "Текущая строка входного файла" // - отрезаем 'r ' ; // "Обработать правило трансформатора" : "Тут разбираем синтаксис MDA" RULES "Строка начинается с" ': ' "Разобрать заголовок стереотипа" "Строка начинается с" '%f ' "Разобрать заголовок функции стереотипа" "Строка начинается с" '%t ' "Разобрать заголовок трансформатора стереотипа" "Строка начинается с" '+ ' "Разобрать заголовок генератора" "Строка начинается с" 'f ' "Разобрать заголовок глобальной функции" "Строка начинается с" 't ' "Разобрать заголовок глобального трансформатора" "Строка начинается с" '# ' "Обработать включение файла" ( "Строка начинается с" ' ' И "Был открыт трансформатор" ) "Обработать правило трансформатора" ( "Строка начинается с" "Табуляция" И ( "Была открыта функция" ИЛИ "Был открыт генератор" ) ) "Разбираем код функции шаблона с начала строки" ( "Был открыт генератор" И "Строка начинается с" '= ' ) "Обработать вызов другого генератора" ; // RULES ; // "Тут разбираем синтаксис MDA" : "Обработать строку входного файла" W-STRING IN "Строка считанная из входного файла" "Был признак переноса" := НЕТ "Строка считанная из входного файла" =: "Текущая строка входного файла" : "Обрабатываем значащие строки" "Вывести строку как комментарий. Чтобы в конечном файле было с чем сравнивать" "Тут разбираем синтаксис MDA" ; // "Обрабатываем значащие строки" RULES "Обрабатываем незначащие строки без перевода строки перед ними" "Ничего не делаем" DEFAULT "Обрабатываем значащие строки" ; // RULES ; // "Обработать строку входного файла" : "Обработать все строки входного файла" "Входной файл" file:ReadLines "Обработать строку входного файла" ; // "Обработать все строки входного файла" false =: "Был открыт стереотип" false =: "Был открыт генератор" false =: "Была открыта функция" false =: "Был открыт трансформатор" 0 =: "Отступ" 0 =: "Количество открытых IF" 0 =: "Количество открытых циклов" 0 =: "Количество открытых скобок параметров функции" false =: "Был отступ" true =: "Накапливаемая строка пустая" false =: "Была кавычка" TRY "Обработать все строки входного файла" FINALLY "Закрыть все скобки" END // TRY..FINALLY FINALLY nil =: "Выходной файл" END // TRY..FINALLY FINALLY nil =: "Входной файл" END // TRY..FINALLY VAR "Имя эталона" "Имя выходного файла" '.etalon.script' Cat =: "Имя эталона" "Имя эталона" "Имя выходного файла" "Пустая строка" tests:CheckOutputWithInput //"Имя выходного файла" "Пустая строка" tests:CheckEtalon ; // "Обработать файл" "Обработанные файлы" := [ ] // 'G:\NewGenTest\TestSet\Auto\fuck.tpi' "Обработать файл" // 'G:\MetaTemplate\Meta\Elements\MDAGenerator.tpi' "Обработать файл" 'G:\F1Specific\F1Specific.tpl' "Обработать файл" /*{ 'G:\VCMTemplates\VCMTemplates.tpl' "Обработать файл" 'G:\CommonTemplates\CommonTemplates.tpl' "Обработать файл" 'G:\CoreTemplates\Integrated\Root\Project.tpi' "Обработать файл" 'G:\CommonTemplates\Integrated\Root\Project.tpi' "Обработать файл" 'G:\CommonTemplates\AllGenerators\DelphiGens\Delphi интерфейсы и реализация.tpi' "Обработать файл" 'G:\CommonTemplates\CommonLang\BaseTypes\PasUtils.tpi' "Обработать файл" 'G:\CommonTemplates\CommonLang\InterfacesMetamodel\AbstractFacet.tpi' "Обработать файл" 'G:\CommonTemplates\CommonLang\InterfacesMetamodel\Facet.tpi' "Обработать файл" 'G:\CommonTemplates\CommonLang\InterfacesMetamodel\PureMixIn.tpi' "Обработать файл" 'G:\VCMTemplates\VCMViewInterfacesLayer\FormOperations\VCMFacet.tpi' "Обработать файл" 'G:\CommonTemplates\CommonLang\BaseTypes\ClassBase.tpi' "Обработать файл" 'G:\CommonTemplates\CommonLang\ImplementationTypes\SimpleClass.tpi' "Обработать файл" //'G:\VCMTemplates\VCMTemplates.tpl' "Обработать файл" 'G:\CommonTemplates\CommonLang\Library\Library.tpi' "Обработать файл" 'G:\MetaTemplate\Meta\Elements\MDAGenerator.tpi' "Обработать файл" 'G:\MetaTemplate\Meta\HighLayers\MDALibrary.tpi' "Обработать файл" 'G:\MetaTemplate\Meta\HighLayers\MDATemplates.tpi' "Обработать файл" // 'G:\CommonTemplates\Integrated\Root\Project.tpi' "Обработать файл" 'G:\CoreTemplates\RequirementsLib\Requirements\Requirements.tpi' "Обработать файл" 'G:\VCMTemplates\VCMSubsystemLayer\SubsystemLevel\VCMSubsystem.tpi' "Обработать файл" }*/ ; // "Обработать шаблоны MDA" "Обработать шаблоны MDA"
Комментариев нет:
Отправить комментарий