Eine Grammatik wird normalerweise als kontextfreie Grammatik definiert - eine genaue Definition finden Sie auf der Wikipedia-Seite, aber sie funktioniert genauso wie bei PLY, das auf Bison basiert , das wiederum auf yacc basiert .
Hier steht , dass PLY einen LALR-Parser verwendet . Hierbei handelt es sich im Wesentlichen um einen LR-Parser, bei dem die Nachschlagetabellen komprimiert werden, was möglicherweise zu Analysekonflikten führt und die Aussagekraft einer LR-Grammatik (dh einer kontextfreien Grammatik, die ein LR-Parser analysieren kann) einschränkt. Wenn Sie sich über die Grenzen dieses besonderen Zweiges von Parsern und die der anderen Parser wissen wollen, ein Überblick über alle Arten von Parsing - Techniken (LL, LR und andere) gegeben hier .
Um Ihre Frage zu beantworten: Es gibt Parsing-Algorithmen, mit denen jede kontextfreie Sprache analysiert werden kann, auch wenn die Sprache mehrdeutig ist (dh es gibt mehr als eine Möglichkeit, die Eingabe zu interpretieren):
Der erste derartige Algorithmus war der CYK-Algorithmus , der leider eine Laufzeit von , wobei n die Länge der Eingabezeichenfolge und | ist G | ist die Größe der Grammatik und daher für das Parsen von Sprachen unpraktisch.O(n3|G|)n|G|
Der zweite Algorithmus ist der Earley-Algorithmus . Dieser Algorithmus kann auch jede kontextfreie Grammatik analysieren. Obwohl der Algorithmus Zeit benötigt, um eine mehrdeutige Sprache zu analysieren, benötigt er nur O ( n 2 ) Zeit, um eine eindeutige Sprache zu analysieren. Außerdem funktioniert es für die meisten LR-Grammatiken anscheinend in linearer Zeit und besonders gut für linksrekursive Grammatiken.O(n3)O(n2)
Hier finden Sie eine Abhandlung über die praktische Implementierung (Anpassung) des Earley-Algorithmus. Sie schließen daraus: "Angesichts der Allgemeingültigkeit des Earley-Parsings im Vergleich zu LALR (1) und der Tatsache, dass selbst PEPs ((deren Implementierung des Earley-Algorithmus)) die schlechteste Zeit für a nicht wahrnehmbar wären Benutzer, das ist ein hervorragendes Ergebnis ".
Der letzte Parsertyp ist der GLR-Parser . Dies ist eine verallgemeinerte Version des LR-Parsings, mit der jede kontextfreie Sprache analysiert werden kann.
Eine ausgereifte Implementierung von GLR ist ASF + SDF . Bison kann auch einen GLR-Parser generieren, obwohl seine Implementierung sich geringfügig vom 'Standard'-GLR-Algorithmus unterscheidet. Der Elkhound-Algorithmus ist ein GLR / LALR-Hybridalgorithmus. Wenn möglich, wird LALR und bei Bedarf GLR verwendet, um sowohl schnell als auch in der Lage zu sein, jede Grammatik zu analysieren.
Über die kontextfreien Grammatiken hinaus gibt es kontextsensitive Grammatiken , die jedoch im Allgemeinen schwer zu analysieren sind und nicht so viel Aussagekraft hinzufügen: Sie können mehr daraus machen, aber für die meisten Anwendungen sind die zusätzlichen Verwendungen nicht relevant, es sei denn, Sie analysieren eine natürliche Sprache.
Als letzter Schritt gibt es uneingeschränkte Grammatiken . Zu diesem Zeitpunkt ist die Grammatik Turing-vollständig, sodass man nicht festlegen kann, wie lange es dauern wird, eine bestimmte Sprache zu analysieren, was für die meisten Parsing-Anwendungen unerwünscht ist. Die Extraleistung wird fast nie benötigt. Wenn Sie die gesamte Leistung nutzen möchten, steht Ihnen die Sprachmaschine zur Verfügung.
Schließlich ist die Implementierung eines eigenen Parser-Generators keine triviale Angelegenheit, insbesondere, um eine schnelle Implementierung zu erreichen. Ich persönlich habe gerade meine eigene Version von flex (dem Lexer-Generator) fertiggestellt, und obwohl dies eine Übung für relativ einfache algorithmische Probleme zu sein schien, wurde es ziemlich kompliziert, die richtigen zu finden, insbesondere, als ich versuchte, Unicode zu unterstützen. Ziehen Sie in Betracht, eine bereits vorhandene Implementierung zu verwenden, anstatt Ihre eigene zu schreiben.