Download Endbericht
Transcript
3.3. PARSER 153 tibilitätsmethoden aus den Infrastrukturklassen, auf den aktuellen Stand gebracht. 3.3.2.4 Anwendung Der Parser befindet sich in der Klasse aaa.parser.PresburgerParser und wird mit der Methode PNode parse(String) aufgerufen. Der Methode wird ein Ausdruck der Presburger Logik übergeben und gibt den dazu gehörenden Ausdrucksbaum als PNode zurück. Dabei ist zu beachten, dass dieser Parser das Kompatibilitätsinterface für Tokens (siehe 3.3.1.1) und PNodes (siehe 3.3.1.1.8) verwendet. Zu beachten ist, dass das Feld position einer ParseException (siehe 3.3.1.1.13) u. U. nicht den genauen Fehlerort anzeigt. 3.3.2.5 Kritik Einer der Vorteile dieses Parsertyps ist es, weit mehr Grammatiken parsen zu können, als übliche tabellengesteuerte LL(k)-Parser. Weiterhin ist die Optimierung und die eigentliche Implementierung einfach und schematisch zu verwirklichen. Als Nachteil stellt sich allerdings heraus, dass es sehr schwer ist, Aussagen darüber machen zu können, an welcher Stelle sich ein syntaktischer Fehler im Eingabestrom befindet. Das resultiert aus der Tatsache, dass die Technik verlangt, unter Umständen an einer Stelle viele mögliche Ableitungsalternativen auszuprobieren, die jeweils korrekte Teilresultate liefern können, ohne dass auch nur eine zum Erfolg führt. Als weiterer kleinerer Nachteil, der aus der Top-Down-Analyse herrührt, ist, dass alle Grammatiken von Linksrekursion befreit sein müssen, als auch, dass Operatorpräzedenzen nur über eine Änderung der Grammatik zu verwirklichen sind. Wird dies nicht getan, liegt es am Auswerter, eine solche, durch Änderung der Auswertungsreihenfolge und -richtung, zu verwirklichen. Gerade Letzteres führte dazu, dass davon abgesehen wurde, diese Art des Parsers weiter zu verwenden. 3.3.3 Second-Generation (LTL, CTL, While) Die Parser der zweiten Generation sind allesamt vorausschauende Parser mit ShuntingYard (siehe 3.3.3.1), zur Umsetzung von Operatorenpräzedenzen. Die Technik, die ein vorausschauender Parser verwendet ist ähnlich dem des rekursivabsteigenden Parsers mit Backtracking (siehe 3.3.2) mit dem Unterschied, dass keine Rücksprünge erfolgen: Der Parser erkennt die richtige Ableitung anhand des nächsten Tokens im Eingabestrom.