Вы должны токенизировать свои данные перед запуском такого рода процесса. (Я не могу рекомендовать знаменитую Книгу Дракона достаточно высоко - даже древнее издание выдержало испытание временем, обновленная версия 2006 года выглядит великолепно). Компиляция - это вид работы, который лучше всего разбить на более мелкие фазы: если ваша первая фаза выполняет лексический анализ на токены, разбивая строки на ключевые слова, идентификаторы, константы и т. Д., То гораздо проще найти ссылки на макросы и посмотреть их в таблице символов. (Также сравнительно проще использовать такой инструмент, как lex или flex или один из их современных эквивалентов, чтобы выполнить эту работу за вас, чем пытаться сделать это с нуля).
Кажется, что «подсказка» равна , если в коде больше макросов, тогда генерация кода занимает так много времени . Похоже, что процесс линейный по числу макросов, что, безусловно, слишком много. Я предполагаю, что этот процесс происходит по одной строке за раз (если ваш язык позволяет это, очевидно, это имеет огромное значение, поскольку вам не нужно обрабатывать программу как одну огромную строку), а псевдокод выглядит примерно так:
for(each line in the program)
{
for(each macro definition)
{
test if the macro appears;
perform replacement if needed;
}
}
Это явно зависит от количества макроопределений.
С токенизацией это выглядит примерно так:
for(each line in the program)
{
tokenize the line;
for(each token in the line)
{
switch(based on the token type)
{
case(an identifier)
lookup the identifier in the table of macro names;
perform replacement as necessary;
....
}
}
}
, который масштабируется в основном по размеру программы (а не по количеству определений) - поиск таблицы символов, конечно, можно выполнить с более оптимальными структурами данных, чем циклически проходить через них все, чтобы больше не становиться существенным фактором. Этот второй шаг - это то, что снова программы, такие как yacc и bison (и их более современные варианты), могут с радостью генерировать код для выполнения.
запоздалая мысль: при разборе макроса определений вы также можете сохранить их как поток токенов и отметить идентификаторы, которые являются именами-заполнителями для замены параметров. При расширении макроса переключитесь на этот поток токенов. (Опять же, что-то вроде flex легко может сделать).