Задача Трассировки (построение графа функций) - страница 5

 
jartmailru:
Статический анализ кода... Исполнение не требуется.

я думал и над другим вариантом - синтаксический разбор текста. так скажем парсинг MQL и создание структуры программы.
но к её реализации даже не знаю с чего подступится. практики не было.

 
tara:

Почему-бы и нет, если хочется.

Выбор неправильного средства реализации говорит о непрофессионализме.
 
MetaDriver:

Неужели неочевидна нерешаемость этой задачи? Эдак можно было бы упразнить пары арифметических () [] и операторных {} скобок, и заменить на единственную - открывающую. Слабо?

;)

Почему же.

Ведь не мало и унарных операций.


jartmailru:
Выбор неправильного средства реализации говорит о непрофессионализме.

да какая разница на чем программить. В любом деле важна матмодель решения.
Все остальное не имеет
 
jartmailru:
Статический анализ кода... Исполнение не требуется.
Код бьётся на функции (блоки) - дальше анализируется кто кого вызывает.

У меня тоже такая мысль бродит. Только всю программу придётся досконально парсить, дабы отделить горы от прыщей...

Да и топикстартеру похоже не это нужно, ежли я правильно проинтуичил ему надо чтоб распечатывались вызовы по факту. Ну типа если условия вызова состоялись.

 
sergeev:

я думал и над другим вариантом - синтаксический разбор текста. так скажем парсинг MQL и создание структуры программы.
но к её реализации даже не знаю с чего подступится. практики не было.

Элементарно.
Что есть функция?
.
[ словечко пробел / этого может и не быть ] словечко имя функции скобочка "(", что-то там, скобочка закрывающая ")"
фигурная открывающая {
.
какой-то код
фигурные скобки считаем парами {, }
.
фигурная закрывающая }
.
Первая часть работы сделана.
 
sergeev:

:))

задача (если читали первый пост) сводится к добавлению всего одной служебной-функции в каждую функцию исходного кода - сразу после "{".

Но с таким расчетом, чтоб получить все проходы исходного кода и построить дерево вызовов.

При этом никоим образом не меняется ни входные параметры исходных функций, ни их результаты или код внутри



Не про чистый трейс идет речь. А только про построение графа функций.

Вот фрагмент журнала:

01:45:18 CTA0 USDCHF,H1: loaded successfully
01:45:18 CTA0 USDCHF,H1 inputs: BarsBeforeActivate=1; BarsBeforeConfirm=0; TraceIsAllowed=true; IsStaticMode=false; ClearAtFinish=true; ExcludeFirstBar=false; ExcludeLastBar=true; RasingLinesColor=(0,128,128); ReducingLinesColor=(255,0,255); 
01:45:18 CTA0 USDCHF,H1: Init
01:45:18 CTA0 USDCHF,H1: Init=>NewBar(DeadLine)
01:45:18 CTA0 USDCHF,H1: Init=>InitType
01:45:18 CTA0 USDCHF,H1: Init=>InitType
01:45:18 CTA0 USDCHF,H1: Init=>InitType
01:45:18 CTA0 USDCHF,H1: Init=>InitType
01:45:18 CTA0 USDCHF,H1: Init=>InitType
01:45:18 CTA0 USDCHF,H1: Init=>InitType
01:45:18 CTA0 USDCHF,H1: Init=>InitType
01:45:18 CTA0 USDCHF,H1: Init=>InitType
01:45:18 CTA0 USDCHF,H1: Init=>InitType
01:45:18 CTA0 USDCHF,H1: Init=>InitType
01:45:18 CTA0 USDCHF,H1: Init=>InitType
01:45:18 CTA0 USDCHF,H1: Init=>InitType
01:45:18 CTA0 USDCHF,H1: Init=>InitType
01:45:18 CTA0 USDCHF,H1: Init=>DeleteGroup(Init)
01:45:18 CTA0 USDCHF,H1: Init=>LoadGroup(ClearScreen)
01:45:18 CTA0 USDCHF,H1: Init=>LoadGroup(ClearScreen)=>ClearGroup
01:45:18 CTA0 USDCHF,H1: Init=>LoadGroup(ClearScreen)=>ClearGroup=>ClearTrend
01:45:18 CTA0 USDCHF,H1: Init=>LoadGroup(ClearScreen)=>ClearGroup=>ClearTrend=>ClearTrace
01:45:18 CTA0 USDCHF,H1: Init=>LoadGroup(ClearScreen)=>ClearGroup(Empty)
01:45:18 CTA0 USDCHF,H1: Init=>LoadGroup(ClearScreen)=>ClearGroup(Empty)=>ClearTrend
01:45:18 CTA0 USDCHF,H1: Init=>LoadGroup(ClearScreen)=>ClearGroup(Empty)=>ClearTrend=>ClearTrace
01:45:18 CTA0 USDCHF,H1: Init=>LoadGroup(ClearScreen)=>SaveGroup(Empty)
01:45:18 CTA0 USDCHF,H1: Init=>PaintGroup(ClearScreen)
 
sergeev:

Почему же.

Ведь не мало и унарных операций.

Ну так данная операция явно не унарна. "Состояние вложенности" при статическом анализе текста - унарно. При динамической трассировке - бинарно. Есть ВХОД и есть ВЫХОД.

Не?

 
MetaDriver:

У меня тоже такая мысль бродит. Только всю программу придётся досконально парсить, дабы отделить горы от прыщей...

Да и топикстартеру похоже не это нужно, ежли я правильно проинтуичил ему надо чтоб распечатывались вызовы по факту. Ну типа если условия вызова состоялись.

При парсинге - вызовы по факту сами обнаружатся. Кто с кем и откуда...

поэтому пока что это единственное завершенная идея решения.

 
Никакого "досконального" парсинга нет так же как "гор" и "прыщей"...
.
Кстати... добавлю:
.
- изначально текст программы анализируется "лексером".
Лексер бьет текст программы на "токены".
В нашем случае токенами являются:
.
- whitespace - пробелы, табуляции, концы строк и т.д. -
раз пишем не форматтер, просто игнорируем этот stuff
- скобки ( / )
- скобки [ / ]
- скобки { / }
- операторы + - / *
- служебные символы ;,
всё остальное по сути является идентификаторами
(числа тоже войдут в эту группу- но нам все равно).
.
При парсинге лексинге заполняются структурки типа
struct { типТокена, строкаТокена }
.
Для парсинга я использовал вложение типа
struct Tocken { типТокена, строкаТокена, list<Token> список вложенных токенов }
но здесь можно подумать как проще.
.
А дальше выполнить группировку о которой я говорил выше- тривиально.
.
Собственно, сочетание лексер + парсер- это классика жанра.
По поводу lex/flex/bison/ant-lr не проконсультирую (я даже названий таких не знаю ;-D)-
я писал именно hand-made.
 

ок. спасибо всем за диспут.

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