Syntaktische Analyse (Parsen)

Werbung
Syntaktische Analyse (Parsen)
Gegeben:
eine kontextfreie Grammatik G und ein String w.
Fragen:
Vorgehen:
gehört w zu L(G)?
Welche Bedeutung hat w?
Konstruiere Herleitungsbaum zu w
P raktische Inf ormatik
2005, F olien Kap.4,−2,
2, SS
(15. Juni2005)
Seite 1
Syntaktische Analyse eines Programms
Gegeben:
Syntax einer Programmiersprache
und der Quelltext eines Programms.
Frage:
ist dies ein syntaktisch korrektes Programm?
Was soll dieses Programm bewirken ?
Aufgabe:
Ermittle Bedeutung“ des Programms,
”
Konstruktionsverfahren für Herleitungsbäume
(bzw. Syntaxbäume)
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 2
Syntaktische Analyse bzgl einer CFG
•
Für jede CFG gibt es einen Parse-Algorithmus
mit worst case Laufzeit O(n3)
(n : Anzahl der Eingabesymbole)
CYK: Cocke, Younger, Kasami,
falls Grammatik in Chomsky-Normalform
(Alle Regeln von der Form N → W mit |W | ≤ 2
oder Earley-Algorithmus
CYK benutzt dynamisches Programmieren.
erzeugt ein Tabelle: pro Paar (N, w) von Nichtterminal N und Wort w
ein Eintrag True wenn N →∗G w, sonst False
Beschränkung: w sind Unterstrings des Eingabewortes
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 3
Syntaktische Analyse bzgl einer CFG
Praxis:
Für jede Programmiersprache
gibt es einen Parser, der effizient arbeitet,
d.h. in O(n), oder in O(n ∗ log(n))
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 4
Parse-Methoden und Beschränkungen
Beschränkung in dieser Vorlesung auf
•
einfach implementierbare oder effiziente
•
Nur für eingeschränkte CFGs
•
Verarbeitung des Zeichenstroms bzw. des Eingabewortes
von links nach rechts
•
evtl. auch mit Vorausschau um einige Zeichen.
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 5
Parse-Methoden: Vorgehensweisen:
Top-Down: Es wird versucht eine Herleitung vorwärts,
vom Startsymbol aus, zu bilden ( forward-chaining“)
”
Bottom-Up: Es wird versucht eine Herleitung rückwärts,
vom Wort aus, zu bilden . ( backward-chaining“).
”
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 6
Parse-Methoden: Vorgehensweisen:
Weiteres Unterscheidungsmerkmal:
R : Konstruktion einer Rechtsherleitung
L : Konstruktion einer Linksherleitung
Gängige Kombinationsmöglichkeiten:
•
•
Top-Down-Verfahren zur Konstruktion einer Linksherleitung
Bottom-Up-Verfahren zur Konstruktion einer Rechtsherleitung
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 7
Beispiel
S
A
B
::=
::=
::=
AB
0 | 1
8 | 9
Frage: Kann 09“ aus dieser Grammatik hergeleitet werden?
”
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 8
09-Beispiel: Top-down:
Start mit Startsymbol S
Rate die Produktionen; Nutze den zu parsenden String zur Steuerung
Bilde Restproblem
Ziel: Eingabestring bis zum Ende verarbeiten.
Ziel
NT-Wort
Herleitung
09
S
S
09
AB
AB
9
B
0B
ε
09
Die erzeugte Herleitung ist eine Linksherleitung.
Beachte
P raktische Inf ormatik
09“ wird von links nach rechts bearbeitet
”
Jedes Eingabezeichen bestimmt eindeutig die Produktion
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 9
09-Beispiel: Bottom-up:
Vorgehen:
Regeln rückwärts auf den gegebenen String anwenden
das Startsymbol der Grammatik ist zu erreichen
09 ← A9 ← AB ← S
Eine Rechtsherleitung wurde konstruiert
Beachte:
Manchmal sind mehrere Regeln anwendbar
Manchmal muss man den Teilstring raten,
auf den eine Produktion (rückwärts) angewendet werden soll
Im Beispiel: Gleicher Herleitungsbaum
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 10
Beispiel: Suche nach der Herleitung
S
A
B
::=
::=
::=
A |B
0A | 1
0B | 2
Kann 002“ hergeleitet werden?
”
Ziel
NT-Wort
Herleitung
002
S
S
002
A
A
02
A
0A
2
A
00A
?
002“ kann nur aus B hergeleitet werden:
”
Ziel
NT-Wort
Herleitung
P raktische Inf ormatik
2, SS
002
S
S
002
B
B
2005, F olien Kap.4,−2,
02
B
0B
(15. Juni2005)
2
B
00B
Seite 11
002
Beispiel: Bemerkungen
Ein deterministischer Top-Down-Parser
muss beim ersten Zeichen von 002“ entscheiden,
”
ob A, oder B.
Diese Wahl kann falsch sein.
Misslingt eine Herleitung, so muss der Parser zurücksetzen
Backtracking“
”
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 12
Rekursiv absteigende Parser
Rekursiv absteigender Parser / Syntaxanalyse
ist an der Form der Regeln der Grammatik orientiert
Methode: Top-Down-Prüfung der Anwendbarkeit der Regeln
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 13
Struktur eines rekursiv absteigenden Parsers
•
Top-Down bzgl. der Grammatik.
•
Eingabewort von links nach rechts
•
Backtracking, falls Sackgasse
•
Konstruktion einer Linksherleitung
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 14
Struktur eines rekursiv absteigenden Parsers
•
•
Pro Nichtterminal N existiert ein Parser PN
der die formale Sprache zu N erkennt.
Eingabe: String
Ausgabe: Syntaxbaum zu Prefix der Eingabe;
Reststring
Parser zu G ist Pσ zum Startsymbol σ
•
Gegeben alle N -Regeln: N → w1 | . . . | wn
PN probiert für alle wi aus,
ob diese zum Anfang des Eingabestrings passen
Passt keine, dann Fehlschlag“
”
•
Prüfung, ob eine Regel ob N → w1 passt:
wi = wi1wi2 . . . wim von links nach rechts durchgehen
Jeweils Parser Pwij aufrufen.
I.a. rekursiver Aufruf, falls wij Nichtterminal.
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 15
Eigenschaften eines rekursiv-absteigenden
Parsers
•
•
•
•
•
I.a. exponentiell.
Liefert alle Linksherleitungen für alle Präfixe
Leicht implementierbar
Leicht erweiterbar auf weitere Einschränkungen
Terminiert nicht für bestimmte (linksrekursive) Grammatiken,
obwohl eine Herleitung existiert:
Beispiel A ::= A+A | A-A | 1 | . . . | 9
Eingabe: 1+1 : Aber: nur die erste Regel wird (jeweils rekursiv) versucht:
(A,1+1) → (A+A,1+1) → ((A+A)+A, 1+1) → . . .
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 16
Rekursiv-absteigende Parser
Anmerkung
Programme von Programmiersprachen kann man i.a.
in O(n) oder O(n ∗ log(n)) parsen,
Effiziente rekursiv-absteigende Parser benötigen i.a.:
•
Erweiterungen wie Vorausschau
•
Umbau der Grammatik (Optimierung der Grammatik)
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 17
Funktionale Kombinator-Parser
Implementierung von rekursiv-absteigenden Parsern in Haskell
Vorteile
relativ leicht verständliche Programmierung
1-1-Übersetzung der Regeln in Programmcode
Pro Nichtterminal N eine Funktion parserN:: String -> [(String, R)]
Präfix der Eingabe 7→
(Rest der Eingabe, Resultat (z.B. Syntaxbaum) )
Um Backtracking zu implementieren:
Liste von erfolgreichen Ergebnissen
verzögerte Auswertung ergibt richtige Reihenfolge der Abarbeitung.
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 18
Haskell-Implementierung der
Parser-Kombinatoren
Kombinator (kombiniert Parser)
Z.B. Alternative, Sequenz, Resultat-Umbau
module RekParsKomb where
import Char
infixr 6 <*>, <*, *>
infixr 4 <|>, <!>
infixl 5 <@
type Parser a b = [a] -> [([a],b)]
erkennt ein Zeichen:
symbol :: Eq s => s -> Parser s s
symbol a []
= []
symbol a (x:xs) | a ==x
= [(xs,x)]
| otherwise
= []
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 19
Haskell: Parser-Kombinatoren (2)
erkennt einen String:
token :: Eq s => [s] -> Parser s [s]
-- token :: Eq s => [s] -> Parser s [s]
token k xs | k == (take n xs)
= [(drop n xs, k)]
| otherwise
= []
where n = length k
testet ein Zeichen der Eingabe:
satisfy
satisfy
satisfy
epsilon
epsilon
:: (s -> Bool) -> Parser s s
p [] = []
p (x:xs) = [(xs,x) | p x]
:: Parser s ()
xs = [(xs,())]
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 20
Haskell: Parser-Kombinatoren (3)
immer erfolgreich:
succeed :: r -> Parser s r
succeed v xs = [(xs,v)]
immer fehlschlagend:
pfail :: Parser s r
pfail xs = []
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 21
Haskell: Parser-Kombinatoren (4)
Sequenzkombinator :
(<*>) :: Parser s a -> Parser s b -> Parser s (a,b)
(p1 <*> p2) xs = [(xs2, (v1,v2))
| (xs1,v1) <- p1 xs,
(xs2,v2) <- p2 xs1]
Alternativkombinator :
(<|>) :: Parser s a -> Parser s a -> Parser s a
(p1 <|> p2) xs = p1 xs ++ p2 xs
Alternativkombinator-2: nur das erste Ergebnis:
(<!>) :: Parser s a -> Parser s a -> Parser s a
(p1 <!> p2) xs = take 1 (p1 xs ++ p2 xs)
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 22
Haskell: Parser-Kombinatoren (5)
ignoriert Blanks am Anfang:
sp :: Parser Char a -> Parser Char a
sp p = p . dropWhile isSpace
eliminiert alle Whitespaces:
wsp :: Parser Char a -> Parser Char a
wsp p = p . filter (\x -> not (isSpace x))
testet, ob die ganze Eingabe konsumiert wurde :
just :: Parser s a -> Parser s a
just p = filter (null . fst) . p
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 23
Haskell: Parser-Kombinatoren (6)
Operation auf dem Ergebnis des Parse :
(<@) :: Parser s a -> (a-> b) -> Parser s b
(p <@ f) xs = [(ys, f v) | (ys,v) <- p xs]
– ignoriert rechtes Ergebnis:
(<*) :: Parser s a -> Parser s b -> Parser s a
p <* q = p <*> q <@ fst
ignoriert linkes Ergebnis:
(*>) :: Parser s a -> Parser s b -> Parser s b
p *> q = p <*> q <@ snd
list (x,xs) = x:xs
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 24
Haskell: Parser-Kombinatoren (7)
erkennt Folge. d.h. entspricht *:
many :: Parser s a -> Parser s [a]
many p = p <*> many p <@ list
<|> succeed []
many1 p = p <*> many p <@ list
digit :: Parser Char Int
digit = satisfy isDigit <@ f
where f c = ord c - ord ’0’
erkennt Zahl:
natural :: Parser Char Int
natural = many1 digit <@ foldl f 0
where f a b = a*10 + b
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 25
Haskell: Parser-Kombinatoren (8)
Nimmt nur die erste (maximale) Alternative des many: nur erlaubt,
wenn die Grammatik diese Alternativen nicht benötigt
manyex :: Parser s a -> Parser s [a]
manyex p = p <*> many p <@ list
<!> succeed []
many1ex p = p <*> manyex p <@ list
option p = p <@ (\x->[x])
<!> epsilon <@ (\x-> [])
Nimmt nur die erste (maximale) Alternative bei Zahlen:
naturalex :: Parser Char Int
naturalex = many1ex digit <@ foldl f 0
where f a b = a*10 + b
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 26
Haskell: Parser-Kombinatoren (9)
Erkennt Klammerung und ignoriert den Wert der Klammern:
pack:: Parser s a -> Parser s b -> Parser s c -> Parser s b
pack s1 p s2 = s1 *> p <* s2
Erkennt Infix-Folge wie z.B. (1+2+3+4+5): Liste der Argumente:
opSeqInf psymb parg = (parg
<*> many (psymb *> parg))
paarf f = \(x,y) -> f x y
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 27
<@ list
Beispiel arithmetische Ausdrücke
Grammatik
Ex
Plus
PlusRest
SigZ
B
Z
P raktische Inf ormatik
2, SS
::=
::=
::=
::=
::=
::=
Plus
SigZ | SigZ Plusrest
+ SigZ PlusRest | eps
B | - B
Z | ( Ex )
0 | ... | 9
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 28
Beispiel arithmetische Ausdrücke
plusausdruecke = just pAriEx
pAriEx :: Parser Char Integer
pAriEx
pAriPlus
= (wsp pAriPlus)
= (opSeqInf (symbol ’+’) pAriSigZ) <@ sum
Die direkte Implementierung wäre:
(pAriSigZ <*> many ((symbol ’+’) *> pAriSigZ)) <@ list
pAriZsymbol = naturalex
pAriSigZ
= pAriB <|> (symbol ’-’) *> pAriB <@ (negate)
pAriB
= pAriZsymbol <|> (pack (symbol ’(’) pAriEx (symbol ’)’))
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 29
Rekursiv-prädiktive Parser
Optimierte rekursiv absteigende Parser
für eingeschränkte Grammatiken ( LL(1) ).
Eigenschaft
Die anzuwendende Produktion ist immer eindeutig festgelegt
•
•
abhängig vom aktuellen Nichtterminal und
dem nächsten Symbol der Resteingabe (Lookahead-Symbol)
•
•
Aber:
kein Zurücksetzen notwendig,
deterministisch Abarbeitung der Eingabe von links nach rechts
man kann nicht für jede kontextfreie Grammatik
einen rekursiv-prädiktiven Parser konstruieren.
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 30
Rekursiv-prädiktive Parser
Eindeutige Zuordnung:
(Lookahead-Symbol, aktuelles Nichtterminal)
Tabellengesteuerter rekursiv-prädiktiver Parser:
Die obige Tabelle inklusive Fehlereinträge
reicht aus zur Steuerung des Parsers
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 31
7→
Regel
Rekursiv-prädiktive Parser
Sind A → w1 | . . . | wn die Regeln zu A und
im Zustand A ist a das erste Symbol der Eingabe:
nur eine Regel A → wi darf anwendbar sein.
Beispiel:
A → bCD | aEF | cG | H
H → dabc
...
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 32
Rekursiv-prädiktive Parser
Sonderrolle:
Es gibt Regel A → wi mit wi →∗ ε:
Diese wird ausgewählt, wenn:
•
•
•
keine passende rechte Seite für das Lookahead-Symbol und
das Lookahead-Symbol kann auf A folgen und
es gibt nur eine solche Regel für A
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 33
Rekursiv-prädiktive Parser, ε-Fall
Beispiel:
S
A
H
...
B
C
→ AB | AC
→ bCD | aEF | cG | H
→ ε
→ dA
→ eA
Im Zustand A und bei Eingabesymbol d:
A → H wird ausgewählt.
Beachte: Gesamtzustand = gesamter Aufrufstack
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 34
FIRST- und FOLLOW-Mengen
Definition Sei G eine CFG mit S als Startsymbol.
Für w ∈ (T ∪ N )∗ und A ∈ N :
first(w)
:=
{x ∈ T | w →∗ xv für ein Wort v ∈ T ∗}
∪{ε} wenn w →∗ ε
follow(A) := {x ∈ T | S →∗ v1Axv2 für Worte v1, v2 ∈ T ∗}
Diese Mengen kann man in allen rekursiv-absteigenden Parsern
zur Vermeidung von Backtracking verwenden.
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 35
Berechnung von first :
Fixpunktiteration:
f0(Ai)
fj+1(Ai)
:=
:=
∅
S
für alle i
i fj (wi) wenn Ai ::= w1 | . . . | wk die Regeln zu A sind.
Stopp, wenn sich nichts mehr ändert.
Hierbei wird verwendet:
fj (aw)
fj (Aw0)
fj (Aw0)
fj (ε)
P raktische Inf ormatik
:=
:=
:=
:=
2, SS
{a} für jedes Terminal a
fj (A) wenn ε 6∈ fj (A)
(fj (A) \ {ε}) ∪ fj (w0) wenn ε ∈ fj (A)
{ε}
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 36
Berechnung von follow :
g0(Ai)
gj+1(Ai)
:=
:=
∅ für alle i
Vereinigung folgender Mengen:
first(w0) ∩ T für jede Regel Ak → wAiw0
gj (Ak )
für jede Regel Ak → wAiw0
mit ε ∈ first(w0)
Stopp, wenn gj+1(A) = gj (A) für alle Nichtterminale A.
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 37
Beispiel für first: Fixpunktberechnung
Ex
Plus
PlusRest
SigZ
B
Z
::=
::=
::=
::=
::=
::=
Plus
SigZ | SigZ Plusrest
+ SigZ PlusRest | eps
B | - B
Z | ( Ex )
0 | ... | 9
Ex
Plus
∅
∅
∅
-,(
0,...,9, (,-
∅
∅
-,(
0,...,9, (,0,...,9, (,-
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
Plus
Rest
∅
+, ε
+, ε
+, ε
+, ε
+, ε
(15. Juni2005)
Seite 38
SigZ
B
Z
∅
-,(
0,...,9, (,0,...,9, (,0,...,9, (,-
∅
(
0,...,9, (
0,...,9, (,0,...,9, (,0,...,9, (,-
∅
0,...,9
0,...,9
0,...,9
0,...,9
0,...,9
Beispiel für follow :
Ex
Plus
PlusRest
SigZ
B
Z
Ex
Plus
)
)
)
)
)
)
∅
)
)
)
)
)
P raktische Inf ormatik
2, SS
::=
::=
::=
::=
::=
::=
Plus
Rest
∅
∅
)
)
)
)
Plus
SigZ | SigZ Plusrest
+ SigZ PlusRest | eps
B | - B
Z | ( Ex )
0 | ... | 9
SigZ
B
Z
+
+
+
+,)
+,)
+,)
∅
+
+
+
+,)
+,)
∅
∅
+
+
+
+,)
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 39
Konstruktion eines rekursiv-prädiktiven Parsers
Bedingungen für die Eindeutigkeit:
•
Für jedes A mit A ::= w1 | . . . | wn
falls ε 6∈ first(wi) für alle i:
die Mengen first(wi) müssen paarweise disjunkt sein.
•
Für jedes A mit A ::= w1 | . . . | wn
falls ε ∈ first(wj ) für ein j:
die Mengen first(wi), i = 1, . . . , n und follow(A) müssen
paarweise disjunkt sein.
•
Für jedes A mit A ::= w1 | . . . | wn
gibt es maximal ein wi mit ε ∈ first(wi)
Parser benötigt Tabelle (Ai, a) 7→ Rj
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 40
Vorgehen des LL(1)-Parsers
Gegeben a, das Symbol und das aktuelle Nichtterminal A:
•
•
•
Ist a ∈ first(wi) für eine Regel A ::= wi, dann nehme diese
Regel.
Ist a 6∈ first(wi) für alle Regeln A ::= wi,
dann gibt es maximal eine Regel A ::= w mit first(w) = ∅
Falls a ∈ follow(A), dann diese Regel.
Wenn auch dann keine passende Alternative existiert, wird mit
Fehler abgebrochen.
Vorteil: genaue und frühe Fehlererkennung
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 41
Beispiel: vereinfachte Grammatik für Ausdrücke
Expr
Rest
Term
•
•
::=
::=
::=
Term Rest
+ Term Rest | − Term Rest | ε
0 | ... | 9
•
•
first(Term Rest) = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
first(+ Term Rest) = {+},
first(− Term Rest) = {−}
first(Expr ) = first(Term ) = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
first(Rest) = {+, −, ε}
•
•
•
follow(Expr) = ∅.
follow(Rest) = ∅.
follow(Term) = {+, −}.
Diese Grammatik hat somit die LL(1)-Eigenschaft.
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 42
Beispielparser zur Grammatik
E
R
T
::=
::=
::=
T R
+ T R | - T R | ε
0 | ...| 9
Die Parsefunktionen haben als Wert: (Resteingabe, Pbaum)
data Pbaum
P raktische Inf ormatik
2, SS
= Pblatt Int
| PExp Pbaum Pbaum
| PRest Char Pbaum Pbaum
| PLeer
deriving (Show, Eq)
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 43
Beispielparser zur Grammatik (2)
parseTerm [] = error "Ziffer erwartet; rest = nil"
parseTerm eingabe@(symbol:rest) =
if not (symbol ‘elem‘ [’0’..’9’] )
then error ("Ziffer erwartet; rest = " ++ eingabe)
else (rest,Pblatt (fst (head (reads [symbol]))))
parseRest [] = ([],PLeer)
parseRest eingabe@(operator: rest) =
if not (operator ‘elem‘ [’+’,’-’] )
then error ("+ oder - erwartet; rest = " ++ eingabe)
else
let (rest1,resultat1) = parseTerm rest
(rest2,resultat2) = parseRest rest1
in (rest2, PRest operator resultat1 resultat2)
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 44
Beispielparser zur Grammatik (3)
parseExp :: [Char] -> (String,Pbaum)
parseExp [] = error ("Ziffer erwartet; rest = nil")
parseExp (eingabe@(symbol: rest)) =
if not (symbol ‘elem‘ [’0’..’9’] )
then error ("Ziffer erwartet; rest = " ++ eingabe)
else
let (rest1,resultat1) = parseTerm eingabe
(rest2,resultat2) = parseRest rest1
in (rest2, PExp resultat1 resultat2)
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 45
Beispielparser zur Grammatik (4)
Testbeispiele:
test1::(String,Pbaum)
test1 = parseExp "1 + 2 - 3"
test2::(String,Pbaum)
test2 = parseExp "1+2-3"
Main> test2
("",PExp (Pblatt 1) (PRest ’+’ (Pblatt 2)
(PRest ’-’ (Pblatt 3) PLeer))) :: (String,Pbaum)
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 46
Beispielparser zur Grammatik (3)
Parsebaum:
PExpLL
1
xx
xx
x
xx
x| x
LLL
LLL
LL&
PRestNNNN
+
qq
qqq
q
q
qq
qx qq
2
−
NNN
NNN
NN&
PRestNNNN
pp
ppp
p
p
ppp
px pp
3
NNN
NNN
NN&
PLeer
Er entspricht der Grammatik,
aber noch nicht der gewünschten Struktur
des arithmetischen Ausdrucks.
Man braucht eine Nachbearbeitung des Parsebaumes.
P raktische Inf ormatik
2, SS
2005, F olien Kap.4,−2,
(15. Juni2005)
Seite 47
Herunterladen