Я пытаюсь построить сканер для компилятора С как язык, и я увлекся эффективным способом генерации токенов … У меня есть функция сканирования:
vector<Token> scan(string &input);
А также основная функция, которая читает лексически правильный файл и удаляет комментарии. (язык не поддерживает /* , */
комментарии) Я использую DFA с максимальным munch для генерации токенов … и я почти уверен, что часть сканера достаточно эффективна. Однако сканер плохо обрабатывает большие файлы, потому что все они заканчиваются одной строкой … и все объединения 1000 строк файла со строкой 1001 нарушают работу сканера. К сожалению, мой FSM не может обрабатывать комментарии, потому что они могут содержать любой Unicode и другие нечетные символы. Мне было интересно … есть ли лучший способ перейти от файла в stdin к вектору токенов, помня, что функция scan должна принимать одну строку и возвращать один вектор, и все токены должны быть в один вектор в конце сканирования … В любом случае, вот код, который «сканирует»: Пожалуйста, не смейтесь слишком над моей плохой идеей 🙂
string in = "";
string build;
while(true)
{
getline(cin, build);
if( cin.eof() )
break;
if(build.find ("//") != string::npos)
build = build.substr(0, build.find("//",0));
in += " " + build;
}
try {
vector<Token> wlpp = scan(in);
...
...
Несколько вещей, которые вы можете рассмотреть:
in += " " + build;
Это очень неэффективно и, вероятно, не хочет, чтобы вы хотели в этом цикле, но это не то, где вы сталкиваетесь с проблемами. (по крайней мере, получить представление о размере ваших входных данных и сделать in.reserve(size)
до этого.
Лучшим дизайном для вашего сканера может быть класс, который упаковывает входной файл как istream_iterator<Token>
и реализовать соответствующий operator>>
для токена. Если вы действительно хотите это в векторе, вы можете сделать что-то вроде vector<Token> v(istream_iterator<Token>(cin), istream_iterator<Token>());
и покончим с этим. Ваш operator>>
затем просто проглотил бы комментарии и заполнил токен, прежде чем вернуться.
Других решений пока нет …