Я пытаюсь реализовать функцию включения в лексере, чтобы при нажатии «#include« имя файла »» он переключался на поток этого файла. Я получил его с помощью действия лексера, показанного ниже. Когда я запускаю его, это вызывает ошибки.
antlr4::ANTLRInputStream new_source(new_file); // new file is an open ifstream
int pos = _input->index();
filestack.push(std::make_pair(_input,pos)); //my stack to keep track of previous files
reset();
_input= static_cast<antlr4::CharStream*>(&new_source);
Я проверил, что static_cast<> работает и возвращает ненулевой указатель, и назначение успешно выполнено. Однако, когда он продолжает работу, он вызывает ошибки после того, как переходит в перекомпилированную среду выполнения ANLTR. Я что-то упускаю?
ОБНОВИТЬ:
Я только что перекомпилировал среду выполнения c ++ с включенными флагами отладки, и теперь я вижу, что в LexerATNSimulator :: failOrAccept происходит сбой, когда возвращается _prevAccept.dfaState-> предсказание.
Кроме того, это то, что происходит до segfault:
It exits out of the custom lexer action and the LexerActionExecutor.
It enters LexerATNSimulator::accept.
exits LexerATNSimulator::accept.
Enters LexerATNSimulator::failOrAccept
Segfault
Я перезагружаю лексер при переключении, это может иметь какое-то отношение к сбою?
Простая замена значения входного потока не обрезает его. Здесь и там есть ссылки, которые могут привести к сбоям. Вместо этого вы должны сбросить источник лексера + токена. Это выглядит так:
lexer.reset();
lexer.setInputStream(&input); // Not just reset(), which only rewinds the current position.
tokens.setTokenSource(&lexer);
Увидеть Код MySQL Workbench на Github для полного полного кода.
Относительно источника токена: лексер является источником токена, и все, что вы можете сделать, это позвонить .reset()
, Посмотри в C ++ источник времени выполнения для деталей этой функции.
Других решений пока нет …