# ablm.py: parser based on
# S ---> b M b
# M ---> ( L | a
# L ---> M a )
import sys
next = None
src = ""
def S ():
if next != 'b':
error(1)
scan()
M()
if next != 'b':
error(2)
scan()
def M ():
if next == '(':
scan()
L()
elif next == 'a':
scan()
else:
error(3)
def L ():
M()
if next == 'a':
scan()
if next == ')':
scan()
else:
error(4)
else:
error(5)
def error(n):
sys.stdout.write("ERROR:" +
str(n))
sys.stdout.write(", SRC:" +
src + "\n")
sys.exit(1)
def getch():
c = sys.stdin.read(1)
if len(c) > 0:
return c
else:
return None
def scan():
global next
global src
next = getch()
if next == None:
sys.exit(1)
while next.isspace(): # whitespace
next = getch()
src += next
scan()
S()
if next == '$':
sys.stdout.write("Success! SRC=" +
src + "\n")
else:
error(0)
| % python ablm.py
b(aa)b$
Success! SRC=b(aa)b$
a(a)b$
ERROR:1, SRC:a
b(((aa)a)a)b$
Success! SRC=b(((aa)a)a)b$
b((aa)a)a)b$
ERROR:2, SRC:b((aa)a)a
bab$
Success! SRC=bab$
baab$
ERROR:2, SRC:baa
b(ba)b$
ERROR:3, SRC:b(b
b((aaa)a)$
ERROR:4, SRC:b((aaa
b((aa)a)b$
Success! SRC=b((aa)a)b$
baba$
ERROR:0, SRC:baba
b(a)b$
ERROR:5, SRC:b(a)
b((((aa)a)a)a)b$
Success! SRC=b((((aa)a)a)a)b$
aba$
ERROR:1, SRC:a
b((ab)a)$
ERROR:5, SRC:b((ab
|