Parsing dieser Art von Sache ist ziemlich einfach (obwohl mühsam) mit rekursiven Abstiegstechniken. Die Idee besteht darin, die zu analysierende Sprache in logische Einheiten zu trennen und dann eine Funktion zu schreiben, um jede dieser Einheiten zu analysieren.
Wenn wir im Beispiel "| 1,2,3,4,15 | (1-> 2), (3-> 2), (4-> 15) | |" dass die gesamte Zeichenfolge ein „Polygon“ ist, würden wir parsePolygon() schreiben, die wie folgt aussehen würde:
void parsePolygon (Buffer& b)
{
parseVertices (b);
parseEdges (b);
}
Nehmen wir an, Buffer eine Klasse, die durch die Zeichenfolge ausgeführt wird. Sie benötigen zwei grundlegende Operationen: Suchen Sie das nächste Zeichen, ohne es zu verbrauchen, und konsumieren Sie das nächste Zeichen.
parseVertices könnte wie folgt aussehen:
void parseVertices (Buffer& b)
{
if (b.peek() != '|') { /* error */ }
b.consume(); // burn the '|'
parseVertexList (b);
if (b.peek() != '|') { /* error */ }
b.consume(); // burn the '|'
}
Sie wollen würde Fehler viel besser, offensichtlich zu handhaben. Wenn der Stream einen Fehler feststellt, muss der Fehlercode den Callstack übergeben oder eine Ausnahme auslösen.
Zwei weitere Beispiele ... parseVertexList und parseNumber könnte wie folgt aussehen:
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);
}
Das alles sehr schnell und schmutzig ist, aber hoffentlich es gibt Ihnen eine Vorstellung davon, wie die Technik funktioniert. Sie können Ihre Handhabung mit Ihrem Parsing mischen, wie oben gezeigt, wo die Funktion parseVertexList tatsächlich den Aufruf von addVertex für Sie aufruft.
Ich denke, das ist wirklich eine der einfachsten Methoden der manuellen Analyse. Im Idealfall könnten wir generierte Parser wie boost spirit oder pyparsing oder lex/yacc verwenden, aber das Leben ist nicht immer so gut, besonders für Hausaufgaben.
Auch ich denke, es ist erwähnenswert, dass die obige Technik eine Menge Overkill für einige Parsing-Situationen sein kann.
Ist das Eingabeformat von Ihnen erfunden? Wenn ja, ändern Sie es in etwas einfacheres. –
Ich muss zustimmen. Diese Syntax ist unnötig komplex. Ein einfacheres Format wäre etwa (1 2 3 4 15) ([1 2] [3 2] [4 15]) – rlbond
Dieses Format ist in der Hausaufgabe angegeben. Ich wünschte, ich könnte es ändern ... – Meir