Новая версия платформы MetaTrader 5 build 2085: Интеграция с Python и массовые улучшения в тестере стратегий - страница 57

 
Vict:

Ну какие это понты? Разве я на сложное решение показал? Оно очень мощно и на все случаи жизни. sed скрипт для вставки __SS__ после каждой { для всех файлов директории очень прост (unix шел):

в винде не сильно по-другому.

ЗЫ: можно пойти дальше - происать __SS__ только в начале функций, а не циклов и т.д, SSHORTY сможет?

Ну так понятно, что не сложно, когда знаешь его.

А сколько понадобится времени тому, кто только что о нем узнал?

 
Andrey Khatimlianskii:

Зачем тогда awk? Можно написать свою "поиск и замену" на С или любом другом языке, которым уже владеешь. Зачем изучать awk? Что он даст?

Почему на С или любом другом языке, когда есть MQL? Причем решение на MQL расширенной задачи (включая построение списка зависимых файлов) занимает значительно меньше по времени, чем рассуждение о способах ее решения на форуме

 

Ну вот и тяжелая артиллерия пожаловала. Может проверим на реальной задаче (через ФП, наверное, вообще как два пальца)? Есть код:

void f(int par_1,
       int par_2,
       int par_3) {
   if (true)
   {
   }
   if (true) {
   }
   for (; false;) {}
   switch (0) {
      case 0:;
   }
   fn();
   do {
   }while(false);
   do
   {
   }
   while(false); 
}
count_t fn_2 () {...}
any_type fn_3(other_type t) {...}
long fn_4(
          other_type t, double) {...}
long fn_5(
           switch_t) {...}
long fn_6(
           _if) {...}

Задача: автоматизированно вставить __SS__ после каждой '{' в начале функции (т.е. после циклов, условий, ... не вставляем).

Свой вариант напишу, если кто-то примет участие с рабочим вариантом, иначе не интересно.

 
Vict:

Задача: автоматизированно вставить __SS__ после каждой '{' в начале функции (т.е. после циклов, условий, ... не вставляем).

И по всей цепочке include-файлов.

 

Тестер последней сборки, похоже, имеет проблему с "Nur Öffnungspreis" (= 4-й вариант моделирования между 1 мин. OHLC и математикой. Calc).

Проблема не появилась со сборкой 2085 и не с 1 мин. OHLC.

Пожалуйста, посмотрите здесь: https://www.mql5.com/de/forum/322168/page3#comment_13239067

The tester of last build seems to have a problem with "Nur Öffnungspreis" (= 4th option of the Modeling between 1 Min. OHLC and math. Calc).

The problem did not appear with build 2085 and not with 1 Min. OHLC.

Please have a look here: https://www.mql5.com/de/forum/322168/page3#comment_13239067
Endlich macht der Metatester wieder Freude
Endlich macht der Metatester wieder Freude
  • 2019.09.16
  • www.mql5.com
Für Programmierer die den MetaTester im visuellen Modus verwenden, empfehle ich dringend das letzte Betarelease(2141) herunter zu laden...
 
Vict:

Задача: автоматизированно вставить __SS__ после каждой '{' в начале функции (т.е. после циклов, условий, ... не вставляем).

Свой вариант напишу, если кто-то примет участие с рабочим вариантом, иначе не интересно.

В общем я тут покумекал, набросал awk скрипт

{
        replacement = "{__SS__; "
        bsz = 30
        b[(bi++) % bsz] = $0;
        if ($0 ~ /.*)[^;]*{/  ||
            ($0 ~ /^[[:blank:]]*{/  &&
             b[(bi-2) % bsz] ~ /.*)[^{};]*$/)) {
                for (pos = bi - 1;  bi - pos <= bsz;  -- pos)
                        if (b[pos % bsz] ~ /.*\(.*/) {
                                if (b[pos % bsz] !~ /if[[:blank:]]*\(/  &&
                                    b[pos % bsz] !~ /for[[:blank:]]*\(/  &&
                                    b[pos % bsz] !~ /while[[:blank:]]*\(/  &&
                                    b[pos % bsz] !~ /switch[[:blank:]]*\(/)
                                        sub("{", replacement)
        
                                break;
                        }
        }
        print
}

код из моего поста он отлично парсит и раставляет __SS__ вначале функций. Потом прогнал через свой реальный код, оказалось, что не всё идеально

   if( this.first_seg_next.get_state() == obst_inactive  &&
       this.first_seg_next.get_point(1) < MYLSEG.get_point(1) )
   {__SS__;
      if(new_top == UPINDEXT_MAX  ||
         this.first_seg_next.get_point(1) > new_top)
         new_top = this.first_seg_next.get_point(1);
   }
почему? суть awk алгоритма - находим {, поднимаемся наверх и ищем что-то похожее на функцию, MYLSEG.get_point(1) похожа. Не то чтобы нельзя допилить, сильного рвения не ощущаю, нужно вести подсчёт открывающихся и закрывающихся скобок и выходить на оператор на самом высшем уровне. 


Ещё приходила идея заюзать clang, ну делают же на нём всякие индексеры, скорее всего можно и здесь "оседлать" clang. Но стоит ли игра свечь ...

В общем свою порцию сексуального удовольствия получил, с дистанции схожу.

ЗЫ: "нужно вести подсчёт открывающихся и закрывающихся скобок и выходить на оператор на самом высшем уровне." хотя можно проще - подниматься до первой }, и проверять отсутствие while, for, ... . И допиливать немного, в общем образец есть, если кому-то очень надо, то есть от чего оттолкнуться.
 
Выпустили бета-версию 2145.
 
Vict:

ЗЫ: "нужно вести подсчёт открывающихся и закрывающихся скобок и выходить на оператор на самом высшем уровне." хотя можно проще - подниматься до первой }, и проверять отсутствие while, for, ... . И допиливать немного, в общем образец есть, если кому-то очень надо, то есть от чего оттолкнуться.

Если изначально выбран правильный стиль, то все в разы проще. По крайней мере у меня получалось в свое время производить замену только в начале функции прямо в MetaEditor-е без дополнительных телодвижений

И Вы правы... для ФП это простейшая задача (на 15 минут) даже с учётом зависимостей

 

A100:

даже с учётом зависимостей

зависимости вообще плёвое дело, ровно две строки - рекурсивный вызов скрипта при встрече include.
 
Vict:

В общем свою порцию сексуального удовольствия получил, с дистанции схожу.

Чёртов перфекционизм, допилил я скрипт:

#awkscr
{
        replacement = "{__SS__; "
        bsz = 30
        b[(bi++) % bsz] = $0
        if (($0 ~ /.*)[^;]*{/  ||
             ($0 ~ /^[[:blank:]]*{/  &&
              b[(bi-2) % bsz] ~ /.*)[^{};]*$/))  &&
            $0 !~ replacement) {
                buf = $0
                sub(/{.*$/, "", buf)
                shift = 1
                if (buf !~ /)/)
                        shift = 2
                opn = 0
                cls = 0
                for (pos = bi - shift;  bi - pos <= bsz;  -- pos) {
                        buf = b[pos % bsz]
                        if (pos == bi - shift)
                                sub(/{.*$/, "", buf)
                        opn += gsub(/\(/, "(", buf)
                        cls += gsub(/)/, ")", buf)
                        if (opn == cls) {
                                if (buf !~ /if[[:blank:]]*\(/  &&
                                    buf !~ /for[[:blank:]]*\(/  &&
                                    buf !~ /while[[:blank:]]*\(/  &&
                                    buf !~ /switch[[:blank:]]*\(/)
                                    sub("{", replacement)
                                break;
                        }
                }
        }
        print
}

Сделал через подсчёт открывающихся/закрывающихся скобок. Тест на реальном коде показал отличный результат. Могут быть какие-нибудь косяки с хитрыми дефайнами:

#define MYERR_HANDLER(INDEX)                                \
{__SS__;                                                            \
   Alert(__FILE__, " ", __LINE__, "-", INDEX, ": error");   \
   this.state = obst_error;                                 \
   return obev_no_event;                                    \
}

Но х.з, может там функция объявляется через макросы, в общем решил не заморачиваться, приемлемо.

Вызывал просто: awk -i inplace -f awkscr 5_trend3.mqh. (-i inplace расширение gnu awk, для других возможно понадобится немного шел обвязки для перезаписи файла. Т.е. направить вывод во временный, удалить начальный, переименовать временный в начальный).

И по всей цепочке include-файлов.

Сделать то не сложно (тупо рекурсивный вызов при встрече include), но тут проблемы кроссплатформенности - у меня linux, а нужно выполнить шел команду, разные слеши, ключи. В общем не стал, проще прогнать все заголовочные файлы (вроде такого: awk -i inplace -f awkscr *), а потом также автоматом удалить __SS__.

Всё, мяч на стороне адептов ФП, удивят ли? Не думаю.

Причина обращения: