Skip to content

Instantly share code, notes, and snippets.

@tjkendev
Last active February 28, 2017 08:44
Show Gist options
  • Save tjkendev/fc3ea9dfd5a1830e57ef5c8ca5e70493 to your computer and use it in GitHub Desktop.
Save tjkendev/fc3ea9dfd5a1830e57ef5c8ca5e70493 to your computer and use it in GitHub Desktop.
LR法を使ったparser (某三実験用につくったもの)
id | ^ & + - * / % ~ ( ) ! $ O X A E T N F I
0 s11 s7 s9 1 2 3 4 5 6 8 10
1 s12 acc
2 r2 s13 r2 r2
3 r4 r4 s14 r4 r4
4 r6 r6 r6 s15 s16 r6 r6
5 r9 r9 r9 r9 r9 s17 s18 s19 r9 r9
6 r14 r14 r14 r14 r14 r14 r14 r14 r14 r14
7 s11 s7 s9 20 8 10
8 r16 r16 r16 r16 r16 r16 r16 r16 r16 r16
9 s11 s7 s9 21 2 3 4 5 6 8 10
10 s23 r19 r19 r19 r19 r19 r19 r19 r19 r19 s22 r19
11 r22 r22 r22 r22 r22 r22 r22 r22 r22 r22 r22 r22
12 s11 s7 s9 24 3 4 5 6 8 10
13 s11 s7 s9 25 4 5 6 8 10
14 s11 s7 s9 26 5 6 8 10
15 s11 s7 s9 27 6 8 10
16 s11 s7 s9 28 6 8 10
17 s11 s29 s7 s9 30 8 10
18 s11 s7 s9 31 8 10
19 s11 s7 s9 32 8 10
20 r15 r15 r15 r15 r15 r15 r15 r15 r15 r15
21 s12 s33
22 r20 r20 r20 r20 r20 r20 r20 r20 r20 r20
23 r21 r21 r21 r21 r21 r21 r21 r21 r21 r21 r21 r21
24 r1 r1 r1 s15 s16 s17 s18 s19 r1 r1
25 r3 r3 r3 s15 s16 s17 s18 s19 r3 r3
26 r5 r5 r5 s15 s16 s17 s18 s19 r5 r5
27 r7 r7 r7 r7 r7 s17 s18 s19 r7 r7
28 r8 r8 r8 r8 r8 s17 s18 s19 r8 r8
29 s11 s7 s9 34 8 10
30 r11 r11 r11 r11 r11 r11 r11 r11 r11 r11
31 r12 r12 r12 r12 r12 r12 r12 r12 r12 r12
32 r13 r13 r13 r13 r13 r13 r13 r13 r13 r13
33 r17 r17 r17 r17 r17 r17 r17 r17 r17 s35 r17
34 r10 r10 r10 r10 r10 r10 r10 r10 r10 r10
35 r18 r18 r18 r18 r18 r18 r18 r18 r18 r18
g 0 S O id
g 1 O O|X |
g 2 O X id
g 3 X X^A ^
g 4 X A id
g 5 A A&E &
g 6 A E id
g 7 E E+T +
g 8 E E-T -
g 9 E T id
g 10 T T**N **
g 11 T T*N *
g 12 T T/N /
g 13 T T%N %
g 14 T N id
g 15 N ~N ~
g 16 N F id
g 17 F (O) id
g 18 F (O)! !
g 19 F I id
g 20 F I! !
g 21 I Ii 10
g 22 I i 1
parser = ""
plist = {}
gram = {}
f = open("LR_table.csv", 'r')
c = 0
def fact(n):
ret = 1
for i in xrange(1,n+1):
ret *= i
return ret
def action(code, st, cc):
if code=='' or code=='id':
# none
return
elif code=='1':
pass
elif code=='10':
arg2 = st.pop()
arg1 = st.pop()
st.append(arg1*10 + arg2)
elif code=='~':
st.append(~st.pop())
elif code=='!':
st.append(fact(st.pop()))
else:
arg2 = st.pop();
arg1 = st.pop();
st.append( eval(str(arg1)+code+str(arg2)) )
return
# read parse table from csv file
for line in f:
s = line.strip().split(',')
if c==0:
parser = s[1:]
elif s[0]=='g':
gram[int(s[1])] = [s[2], s[3], s[4]]
elif s[0]!='':
plist[int(s[0])] = s[1:]
c += 1
# do parsing
dig = "0123456789"
while 1:
ex = False
stack = [0]
calc = []
ch = []
cc = ''
s = raw_input()+'$'
# parse characters one by one
for c in s:
cc = c
if c in dig:
c = 'id'
shift = -1
print "Input ========> ",c
# shift and reduce
while 1:
q = stack[-1]
p = parser.index(c)
mov = plist[q][p]
#print "(%d,%s) => '%s'"%(q,c,mov)
if mov=='':
print "error"
ex = True
break
elif mov=='acc':
print "accept"
ex = True
break
elif mov[0]=='s':
shift = int(mov[1:])
break
elif mov[0] in dig:
shift = int(mov)
break
elif mov[0]=='r':
r = int(mov[1:])
g = gram[r]
#print "(%s -> %s)"%(g[0],g[1])
action(g[2], calc, cc)
arg = []
for i in g[1]:
# code
arg.append(stack.pop());
stack.pop();
qq = stack[-1]
pp = parser.index(g[0])
sh = plist[qq][pp]
#print "(%d,%s) => '%s'"%(qq,g[0],sh)
if sh=='':
print "error : reduce"
ex = True
break
# code
stack.append(g[0])
stack.append(int(sh))
ch.append(r)
else:
print "error"
ex = True
break
#print "stack :", stack
#print "calc :", calc
# error or accept
if ex:
break
if cc in dig:
calc.append(int(cc))
stack.append(c)
stack.append(shift)
print "stack :",stack
print "calc :",calc
print ch
print "calc result :",calc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment