Ich konvertiere eine kontextfreie Grammatik in Greifach Normal Form (GNF). Die Haupttransformation (von Hopcroft & Ullman) ist eine Folge von Iterationen über die indizierten Variablen der Grammatik. Es ist im Wesentlichen "staatenlos". Ich habe es als eine Folge von Falten über den entsprechenden Indizes umgesetzt (die Umsetzung ist recht einfach):Staat in einer zustandslosen Welt halten
gnf :: Ord a => Set (Rule a) -> Set (Rule a)
gnf rl = foldl step1 rl [1..maxIndex rl]
where step1 rl' k = foldl step2 rl' [1..k - 1]
where step2 rl'' j = noLR k (subst rl'' k j)
MaxIndex rl den maximalen Variablenindex in einer Reihe von Regeln gibt; subst rl k j führt Substitution auf die k-indizierten Regeln durch die Regeln, deren rechte Seite beginnt mit einer j -indizierte Variable. Nachdem ich gnf durchgeführt habe, muss ich einen letzten Durchgang über die Grammatik in umgekehrter Reihenfolge durchführen.
Das Problem ist noLR, die eine Grammatik mit linksrekursive k -indexed Regeln transformiert. Dies ist eine "stateful" -Funktion, da für jede Regel (oder k -indexierte Regel) eine eindeutige Variable generiert werden muss, auf die noLR angewendet wird. Also schrieb ich eine Stateful-Funktion
noLR :: Ord a => Int -> Set (Rule a) -> State [Sym a] (Set (Rule a))
noLR rl = do (n:ns) <- get; put ns;
let rl' = ... remove left recursion rl n ...
in return rl'
Ich kann die noLR um sequenzieren zusammen die n zu aktualisieren, die noLR als Parameter annimmt. Ich bin nicht sicher, wie man noLR innerhalb Schritt2 in der obigen Funktion durchzuführen, obwohl. Ich kann das Schema let ... in nicht verwenden, weil die statusbehaftete Berechnung in mehrere rekursive Funktionen eingebettet ist.
Was will ich tun haben n irgendeine Art von globalen Variablen sein, ähnlich wie bei einem expliziten Einfädeln n, die ich innerhalb schritt2 nennen und Update kann, weshalb ich ursprünglich die Funktion geschrieben als eine Falte mit eta -Expansion (für n). Weiß jemand, wie ich gnf innerhalb der Staat Monade strukturieren könnte, um diese Art von Effekt zu erreichen? Bis auf die letzte Berechnung in der Falte ist nichts anderes "stateful", und ich bin nur mit der Zustands-Monade mit "trivialen" Beispielen vertraut. Ich bin ziemlich verloren.
siehe 'foldM'. 'gnf' wird natürlich mit einem evalState-Aufruf der obersten Ebene beginnen. – sclv
+1 für den Titel. – fuz