Разбор такого рода вещей довольно прост (хотя и утомителен) с техникой рекурсивного спуска. Идея состоит в том, чтобы разделить анализируемый язык на логические единицы, а затем написать функцию для анализа каждой из этих единиц.
Если мы приведем пример "| 1,2,3,4,15 | (1-> 2), (3-> 2), (4-> 15) |" что вся строка является «полигоном», мы бы написали parsePolygon (), который бы выглядел примерно так:
void parsePolygon (Buffer& b)
{
parseVertices (b);
parseEdges (b);
}
Давайте предположим, что Buffer - это класс, который проходит через вашу строку. Вам понадобятся две основные операции: взглянуть на следующий символ без его использования и использовать следующий символ.
parseVertices может выглядеть так:
void parseVertices (Buffer& b)
{
if (b.peek() != '|') { /* error */ }
b.consume (); // burn the '|'
parseVertexList (b);
if (b.peek() != '|') { /* error */ }
b.consume (); // burn the '|'
}
Вы бы хотели обрабатывать ошибки намного лучше, очевидно. Если поток сталкивается с какой-либо ошибкой, ему нужно передать код ошибки в стек вызовов или вызвать исключение.
Еще два примера ... parseVertexList и parseNumber могут выглядеть следующим образом:
void parseVertexList (Buffer& b)
{
addVertex (parseNumber (b));
while (b.peek() == ',')
{
b.consume (); // eat the comma
addVertex (parseNumber (b));
}
}
int parseNumber (Buffer& b)
{
char accum[80] = { '0' }; // sensible default in case of failure
int accumPos = 0;
while (isDigit (b.peek())
{
accum[accumPos++] = b.consume();
}
return atoi(accum);
}
Это все очень быстро и грязно, но, надеюсь, это даст вам представление о том, как работает техника. Вы можете смешивать вашу обработку с вашим анализом, как показано выше, где функция parseVertexList фактически выполняет вызовы addVertex для вас.
Я думаю, что это действительно один из самых простых методов ручного разбора. В идеале мы всегда сможем использовать сгенерированные парсеры, такие как boost spirit или pyparsing или lex / yacc, но жизнь не всегда так хороша, особенно для домашней работы.
Также я полагаю, что стоит отметить, что вышеупомянутая техника может быть слишком избыточной для некоторых ситуаций анализа.