1

Eine Grammatik ist regelmäßig, wenn es entweder rechts-linear oder links-linear ist. This tutorial behauptet, dass aus diesem Grunde hat die besondere Eigenschaft:Wie reguläre Grammatik mit Rekursion und Alternationen in reguläre Ausdruck konvertieren

Eine regelmäßige Grammatik hat eine besondere Eigenschaft: von jedem Nicht-End-Substitution (mit Ausnahme der Wurzel eins) mit seiner rechten Seite, können Sie es zu einer Verringerung unten Einzelfertigung für die Wurzel, mit nur Terminals und Betreibern auf der rechte Seite ... die reduzierten Expression von Terminals und Operatoren kann in einer noch kompakten Form geschrieben werden, genannt einen regulären Ausdruck

Also habe ich beschlossen, das zu testen Idee und die Normal-EcmaScript grammar for IdentifierName in Normal-Ausdrücke konvertieren:

IdentifierName :: 
    IdentifierStart 
    IdentifierName IdentifierPart 

Es sei IdentifierStart und IdentifierPart sind beschränkt auf die folgenden:

IdentifierStart ::  IdentifierPart :: 
    A      A     
    B      C 
    C      & 
    $      
    _ 

Aber ich bin nicht sicher, wie da die Grammatik sowohl für IdentifierName muss gehen Rekursion und Alternation. Irgendeine Hilfe?

Ich interessiere mich eher für den Ansatz als für das Finden der resultierenden Regexp, die wie @Bergi zeigte [ABC$_][AC&]*.

+1

Ein IdentifierName ist entweder ein IdentifierName gefolgt von einem IdentifierPart oder einem IdentifierStart, wenn IdentifierStart S ist und IdentifierPart P ist, dann sind einige legale IdentifierNames S, SP, SPP und so weiter ...IE ein S gefolgt von einigen Ps. kannst du an eine Regex denken, um das zu erreichen? –

+0

Nur '[ABC $ _] [AC &] *' – Bergi

+0

@Bergi, danke, aber ich interessiere mich eher für den Ansatz der Ersetzung als für die Regexp selbst. Oder ist das Beispiel zu simpel, so dass es möglich ist, mit der Regexp zu kommen, ohne dem Ansatz zu folgen? –

Antwort

2

Dieses Tutorial verwendet einige nicht standardmäßige (und überraschend implizite) Definitionen.

Zuerst verwenden sie Wiederholungsoperatoren in ihrer Grammatik, wie sie in regulären Ausdrücken oder EBNF gefunden werden könnten. Dann definieren sie implizit eine reguläre Grammatik als eine, die nur diese Wiederholungsoperatoren und keine Rekursion verwendet. Angesichts dessen ist es trivial, eine "reguläre Grammatik" in eine Regex zu verwandeln, indem man einfach alle Nicht-Terminals einordnet. Aber nach dieser Definition ist die Grammatik der JS-Spezifikation für Bezeichner nicht regulär, weil sie Rekursion enthält. Bevor Sie also alles inline einfügen können, müssen Sie zuerst die Rekursion durch Wiederholungsoperatoren ersetzen.

Dies ist jedoch nicht die Standarddefinition dessen, was eine normale Grammatik ist. Die Standarddefinition ist wie gesagt: Eine Grammatik ist regulär, wenn sie entweder links-linear oder rechts-linear ist - das heißt, wenn nur der äußerste linke Teil einer Produktion ein nicht-terminaler oder nur der rechte ist. Wiederholungsoperatoren existieren nicht in der üblichen Definition einer formalen Grammatik.

Nun können diese regulären Grammatiken auch in reguläre Ausdrücke konvertiert werden, jedoch nicht durch bloßes Anwenden der im Lernprogramm beschriebenen Methode. Ein Weg wäre, die Grammatik in einen endlichen Automaten umzuwandeln und dann den Algorithmus anzuwenden, der zum Beispiel in this answer beschrieben ist.

In der Praxis jedoch, wenn Sie die Konvertierung von Hand (anstatt ein Programm zu tun), die einfachste und gebräuchlichste Art, die Konvertierung durchzuführen, ist darüber nachzudenken, welche Sprache die Grammatik beschreibt (in diesem Fall "die Sprache aller Wörter, die mit einem IdentifierStart-Symbol beginnen und dann 0 oder mehr IdentifierPart-Symbole enthalten ") und dann einen regulären Ausdruck erstellen, der diese Sprache ausdrückt (aka der" Schau dir das Problem wirklich an, bis du den Lösungsalgorithmus siehst ") .

+0

danke, also würde dieser Algorithmus funktionieren: 1) Ersetze die Rekursion durch Wiederholungsoperatoren und dann 2) ersetze jedes Nichtterminal (außer der Wurzel) durch seine rechte Seite? Oder ist der erste Teil wirklich nicht trivial, wenn man einen mechanischen Ansatz anwendet? –

+0

schrieb ich auch _Eine Grammatik ist regelmäßig, wenn sie entweder rechts-linear oder links-linear ist. Dieses Tutorial behauptet, dass ** deswegen ** ..._. Es scheint also, dass der Ersatz-Algorithmus nicht funktioniert, sondern wegen des Wiederholungsoperators? –

+1

@ AngularInDepth.com Ja, dieser Algorithmus würde funktionieren, aber "die Rekursion durch Wiederholungsoperatoren zu ersetzen" ist im allgemeinen Fall ein entschieden nicht-trivialer Schritt. Und ja zu Ihrem zweiten Kommentar auch: Der Ersetzungsalgorithmus funktioniert, weil er reguläre Grammatiken nicht als links-lineare oder rechts-lineare Grammatiken definierte (was die übliche Definition wäre), sondern als Grammatiken, die nur Wiederholungsoperatoren anstelle von Rekursion verwenden. – sepp2k