Die obigen Antworten geben eine ziemlich gute Definition dessen, was es ist. Mal sehen, ob ich es in meine eigenen Worte fassen kann, so dass Sie statt 20 23 Erklärungen haben. Der ganze Zweck einer Grammatik, jeder Grammatik, besteht darin, herauszufinden, ob ein bestimmter Satz ein Satz in der gegebenen Sprache ist. Was wir jedoch wirklich mit Grammatik und Syntaxanalyse anfangen, ist herauszufinden, was der Satz bedeutet. Es ist wie das alte Diagramm eines Satzes, den Sie im Englischunterricht in der Schule gemacht haben oder nicht. Ein Satz besteht aus einem Subjektteil und einem Prädikatteil, ein Subjektteil hat ein Substantiv und möglicherweise einige Adjektive, ein Prädikatteil hat ein Verb und möglicherweise ein Objektnomen, mit einigen weiteren Adjektiven usw.
Wenn es eine Grammatik für Englisch gäbe (und das glaube ich nicht, nicht im Sinne der Informatik), gäbe es Regeln der folgenden Form, die als Produktionen bezeichnet werden.
Sentence -> SubjectPart PredicatePart
SubjectPart -> Adjective Noun
usw...
Sie könnten dann ein Programm schreiben und ihm einen beliebigen Satz geben, und das Programm könnte die Grammatik verwenden, um herauszufinden, welcher Teil des Satzes jedes Wort ist und welche Beziehung sie zueinander haben.
Wenn es in jeder Produktion nur eins auf der linken Seite gibt, bedeutet dies, dass Sie immer dann, wenn Sie die rechte Seite im Satz sehen, auf der linken Seite ersetzen dürfen. Wenn Sie zum Beispiel Adjektiv Nomen sahen, konnten Sie "That's a SubjectPart" sagen, ohne auf irgendetwas außerhalb dieser Phrase zu achten.
Englisch (auch die vereinfachte Beschreibung des Englischen, die ich oben gegeben habe) ist jedoch kontextsensitiv. "Adjektiv Nomen" ist nicht immer ein SubjectPart, es könnte eine Nomenphrase in einem PredicatePart sein. Es kommt auf den Kontext an. Lassen Sie uns unsere pseudo-englische Grammatik etwas erweitern:
Sentence -> SubjectPart PredicatePart
SubjectPart -> Adjective Noun
PredicatePart -> VerbPhrase ObjectNounPhrase
VerbPhrase ObjectNounPhrase -> VerbPhrase Adjective Noun
Sie können ein "Adjektiv-Nomen" nur dann in eine ObjectNounPhrase umwandeln, wenn es direkt nach einer VerbPhrase steht.
Grundsätzlich ist eine Produktion, die Sie jederzeit anwenden können, unabhängig von ihrer Umgebung, kontextfrei.
Sie können jederzeit leicht feststellen, ob eine Grammatik kontextfrei ist. Prüfen Sie einfach, ob sich links neben den Pfeilen mehr als ein Symbol befindet.
Jede Sprache kann durch mehr als eine Grammatik beschrieben werden. Wenn eine Grammatik für eine Sprache kontextfrei ist, ist die Sprache kontextfrei. Für einige Sprachen kann nachgewiesen werden, dass keine kontextfreie Grammatik möglich ist. Ich nehme an, es könnte eine kontextfreie Grammatik für die vereinfachte pseudo-englische Teilmenge geben, die ich oben beschreibe.
Um eine kontextfreie Grammatik zu analysieren, ist ein einfacheres Programm erforderlich. Wie in den anderen Antworten erwähnt, ist nicht die volle Leistung einer Turing-Maschine erforderlich, um eine kontextfreie Grammatik zu analysieren. Ein Lookahead LR (1) -Parser (eine Art Pushdown-Maschine) für eine bestimmte kontextfreie Grammatik kann jeden Satz in dieser Grammatik zeitlich und räumlich linear zur Satzlänge analysieren. Wenn der Satz in der Sprache vorliegt, erstellt der Parser einen Strukturbaum, der angibt, was jedes Symbol im Satz bedeutet (oder zumindest welche Rolle es in der Struktur spielt). Befindet sich der Satz nicht in der Grammatik, merkt der Parser, dass das erste Symbol nicht mit der Grammatik und den vorhergehenden Symbolen in Einklang zu bringen ist, und hört auf (beim ersten "Fehler").
Was noch besser ist, ist, dass es Programme gibt, mit denen Sie eine Beschreibung einer Grammatik und eine Liste von Anweisungen dazu geben können, was mit jedem Teil zu tun ist (in gewissem Sinne, indem jeder Produktion eine "Bedeutung" beigemessen wird), und dass das Programm den Parser schreibt für dich. Das Programm analysiert den Satz, findet die Struktur und führt Ihre Anweisungen für jeden Teil der Struktur aus. Diese Art von Programm wird Parser-Generator oder Compiler-Compiler genannt.
Diese Art der Sprachanalyse wurde für die automatische Analyse natürlicher Sprachen (wie Englisch) entwickelt. Es stellt sich jedoch heraus, dass dies für die Analyse von Computersprachen am nützlichsten ist. Ein Sprachdesigner kann eine Grammatik schreiben, die seine neue Sprache erfasst, und diese dann über den Parser-Generator ausführen, um ein Programm zu erhalten, das seine Sprache analysiert und übersetzt, interpretiert, kompiliert, ausführt usw., wenn er dies wünscht.
Tatsächlich kann man das in den meisten Fällen nicht wirklich tun. Beispielsweise sind ausgeglichene Klammern eine kontextfreie Sprache. Eine Sprache, in der alle Variablen deklariert werden müssen, bevor Sie sie verwenden, ist jedoch kontextsensitiv. Der Parser ist Teil des Compilers, es ist jedoch zusätzliche Logik erforderlich, um diese anderen Anforderungen durchzusetzen. Was Sie dann tun müssen, ist, eine Grammatik zu schreiben, die so viel wie möglich von Ihrer Sprache erfasst, diese durch einen Parser-Generator laufen zu lassen und dann Code zu schreiben, der den Rest der Anforderungen erzwingt (Symboltabellen-Handler usw.).
Wir verwenden im Allgemeinen keine kontextsensitiven Grammatiken, da diese viel schlechter unterstützt werden. Ich weiß nicht, ob es für kontextsensitive Sprachen ein Äquivalent zu einem LR (k) -Parser-Generator gibt. Ja, eine Turingmaschine (oder eine linear gebundene Maschine) kann eine analysieren, aber ich weiß nicht, ob es einen allgemeinen Algorithmus gibt, um eine kontextsensitive Grammatik in ein Programm für eine Turingmaschine in dem Sinne zu verwandeln, dass ein LR (1) ) Generator erstellt Analysetabellen für eine Pushdown-Maschine. Ich vermute, dass die Tabellen, die dem Parser zugrunde liegen, exponentiell größer wären. Auf jeden Fall wird CS-Schülern (wie mir selbst damals) normalerweise kontextfreie Grammatik und LR (1) -Parser-Generatoren wie YACC beigebracht.