После прочтения определение antlr v4 book , Я понял, что есть два механизма для прогулки по дереву.
Я хочу создать простой график вызовов для грамматики Cpp.
этот это Cpp14 грамматика.
вот часть правил:
postfixexpression
:
primaryexpression #PrimaryEX
| postfixexpression '[' expression ']' #label9
| postfixexpression '[' bracedinitlist ']' #label10
| postfixexpression '(' expressionlist? ')' #FuncCall
| simpletypespecifier '(' expressionlist? ')' #label11
| typenamespecifier '(' expressionlist? ')' #label13
| simpletypespecifier bracedinitlist #label14
| typenamespecifier bracedinitlist #label15
| postfixexpression '.' Template? idexpression #label16
| postfixexpression '->' Template? idexpression #label17
| postfixexpression '.' pseudodestructorname #label18
| postfixexpression '->' pseudodestructorname #label19
| postfixexpression '++' #label20
| postfixexpression '--' #label21
| Dynamic_cast '<' typeid '>' '(' expression ')' #label22
| Static_cast '<' typeid '>' '(' expression ')' #label23
| Reinterpret_cast '<' typeid '>' '(' expression ')' #label24
| Const_cast '<' typeid '>' '(' expression ')' #label25
| Typeid '(' expression ')' #label26
| Typeid '(' typeid ')' #label27
Мое решение заключается в использовании посетителя и создании метки для всех правил, которые необходимы для определения имени функции.
например, когда я ввожу входной файл t.mainCpp
static void nastaran(int a, int b)
{
}
int main()
{
a=func();
}
дерево парсера это:
и я думаю, что для получения имени каждой функции, которая вызывается в коде, нужно найти это поддерево:
Я имею в виду, что я перезаписываю посетителя для метки FunCall и получаю значение идентификатора, вызывая детей-посетителей postfixexpression.
но я не знаю, является ли это решение правильным или подходящим для этой проблемы или нет. я должен использовать посетителя?
Задача ещё не решена.
Других решений пока нет …