HSG

Aktuelle Seite: HSG/Fächer/Informatik/Material/Bonsai/Bonsai-Compiler/MiniPython-Compiler

Der Scanner liefert dem Parser die Tokens. Der Parser versucht diese Tokenfolge gemäß seiner Grammatik abzuleiten. Die Grammatik steht übersichtlich am Anfang der von PLY erzeugten Datei parser.out.

Created by PLY version 3.4 (http://www.dabeaz.com/ply)

Grammar

Rule 0     S' -> start
Rule 1     start -> kette
Rule 2     kette -> befehl kette
Rule 3     kette -> 
Rule 4     befehl -> whileAnw
Rule 5     befehl -> ifAnw
Rule 6     befehl -> zuw
Rule 7     befehl -> PASS
Rule 8     whileAnw -> WHILE cond : kette END
Rule 9     ifAnw -> IF cond : kette ELSE : kette END
Rule 10    cond -> VAR OP VAR
Rule 11    cond -> VAR OP NUM
Rule 12    cond -> NUM OP VAR
Rule 13    zuw -> VAR = ausdruck
Rule 14    ausdruck -> NUM
Rule 15    ausdruck -> VAR
Rule 16    ausdruck -> VAR + NUM
Rule 17    ausdruck -> VAR - NUM
Rule 18    ausdruck -> NUM + VAR
Rule 19    ausdruck -> VAR + VAR
Rule 20    ausdruck -> VAR - VAR

Terminals, with rules where they appear

+                    : 16 18 19
-                    : 17 20
:                    : 8 9 9
=                    : 13
ELSE                 : 9
END                  : 8 9
IF                   : 9
NUM                  : 11 12 14 16 17 18
OP                   : 10 11 12
PASS                 : 7
VAR                  : 10 10 11 12 13 15 16 17 18 19 19 20 20
WHILE                : 8
error                : 

Nonterminals, with rules where they appear

ausdruck             : 13
befehl               : 2
cond                 : 8 9
ifAnw                : 5
kette                : 1 2 8 9 9
start                : 0
whileAnw             : 4
zuw                  : 6

Um das Zusammenwirken von Scanner und Parser zu zeigen, wurden bei jedem Token und bei jeder Anwendung einer Grammatikregel print-Anweisungen eingefügt. Dafür musste dann auch der Komfort der literalen Token geopfert werden.

tokens = ['VAR','NUM','END','OP',
          'ISTGLEICH','DOPPELPUNKT','PLUS','MINUS'] + list(reserved.values())                       
# literals = "=:+-"
def t_ISTGLEICH(t):
    r'='
    print(t)
    return t

def t_DOPPELPUNKT(t):
    r':'
    print(t)
    return t

def t_PLUS(t):
    r'\+'
    print(t)
    return t

def t_MINUS(t):
    r'\-'
    print(t)
    return t

Test des Parsers minipythonparse.py

>>> p.parse("""a = 23
b = 5

q = 0
r = a
while r>=b:
    r = r-b
    q = q+1
#end
 
print(q)
print(r)""")
LexToken(VAR,'a',1,0)
LexToken(ISTGLEICH,'=',1,2)
LexToken(NUM,23,1,4)
LexToken(VAR,'b',2,7)
ausdruck : NUM
zuw : VAR ISTGLEICH ausdruck
befehl : zuw
LexToken(ISTGLEICH,'=',2,9)
LexToken(NUM,5,2,11)
LexToken(VAR,'q',4,14)
ausdruck : NUM
zuw : VAR ISTGLEICH ausdruck
befehl : zuw
LexToken(ISTGLEICH,'=',4,16)
LexToken(NUM,0,4,18)
LexToken(VAR,'r',5,20)
ausdruck : NUM
zuw : VAR ISTGLEICH ausdruck
befehl : zuw
LexToken(ISTGLEICH,'=',5,22)
LexToken(VAR,'a',5,24)
LexToken(WHILE,'while',6,26)
ausdruck : VAR
zuw : VAR ISTGLEICH ausdruck
befehl : zuw
LexToken(VAR,'r',6,32)
LexToken(OP,'>=',6,33)
LexToken(VAR,'b',6,35)
LexToken(DOPPELPUNKT,':',6,36)
cond : VAR OP VAR
LexToken(VAR,'r',7,42)
LexToken(ISTGLEICH,'=',7,44)
LexToken(VAR,'r',7,46)
LexToken(MINUS,'-',7,47)
LexToken(VAR,'b',7,48)
LexToken(VAR,'q',8,54)
ausdruck : VAR MINUS VAR
zuw : VAR ISTGLEICH ausdruck
befehl : zuw
LexToken(ISTGLEICH,'=',8,56)
LexToken(VAR,'q',8,58)
LexToken(PLUS,'+',8,59)
LexToken(NUM,1,8,60)
LexToken(END,'#end',9,62)
ausdruck : VAR PLUS NUM
zuw : VAR ISTGLEICH ausdruck
befehl : zuw
kette :
kette : befehl kette
kette : befehl kette
LexToken(IGN,'print(q)',11,69)
LexToken(IGN,'print(r)',12,78)
whileAnw : WHILE cond DOPPELPUNKT kette END
befehl : whileAnw
kette :
kette : befehl kette
kette : befehl kette
kette : befehl kette
kette : befehl kette
kette : befehl kette
start : kette
>>> 

Aufgabe

Teste den Parser an kleinen Programmen. Wann versagt er, wann muss er versagen?