Skip to content

Commit

Permalink
reading MBGF is done (in a rather general well-structured way)
Browse files Browse the repository at this point in the history
  • Loading branch information
grammarware committed May 12, 2012
1 parent 7778114 commit 373370b
Show file tree
Hide file tree
Showing 3 changed files with 221 additions and 188 deletions.
103 changes: 103 additions & 0 deletions shared/python/MBGF.py
@@ -0,0 +1,103 @@
#!/Library/Frameworks/Python.framework/Versions/3.1/bin/python3
import os, sys
sys.path.append(os.getcwd().split('slps')[0]+'slps/shared/python')
import slpsns, BGF3
import xml.etree.ElementTree as ET

class TopModel:
def who(self):
return self.__class__.__name__
def parsebasic(self, xml):
if 'id' in xml.attrib:
self.id = xml.attrib['id']
else:
self.id = self.who()
if 'depends' in xml.attrib:
self.depends = xml.attrib['depends']
else:
self.depends = ''
self.data = {}

class SrcSimpleModel (TopModel):
def parse(self, xml):
self.parsebasic(xml)
for ss in xml.findall('src'):
for s in ss.attrib['name'].split(','):
self.data[s] = ss.text

class SrcProdModel (TopModel):
def parse(self, xml):
self.parsebasic(xml)
for ss in xml.findall('src'):
for s in ss.attrib['name'].split(','):
self.data[s] = [[],[]]
for p in ss.findall(slpsns.bgf_('production')):
xp = BGF3.Production()
xp.parse(p)
self.data[s][0].append(xp)
self.data[s][1] = xml.findall('in')

#
# <sources>
# <src name="dcg">snapshot/dcg.bgf</src>
# <src name="sdf">snapshot/sdf.bgf</src>
# <src name="rsc">snapshot/rascal.bgf</src>
# </sources>
class Sources (SrcSimpleModel):
def __init__(self, xml):
self.parse(xml)

# <naming-convention>
# <default>l!</default>
# <src name="dcg">l!</src>
# <src name="sdf,rsc">C!</src>
# </naming-convention>
class NamingConvention (SrcSimpleModel):
def __init__(self, xml):
self.default = xml.findtext('default')
self.parse(xml)

# <width>
# <bgf:expression>
# <nonterminal>newline</nonterminal>
# </bgf:expression>
# <src name="dcg,sdf">+</src>
# <src name="rsc">!</src>
# <in>
# <nonterminal>function</nonterminal>
# </in>
# </width>
class Width (SrcSimpleModel):
def __init__(self, xml):
self.expr = BGF3.Expression([])
self.expr.parse(xml.findall(slpsns.bgf_('expression'))[0])
# apply namemap!!!
self.parse(xml)
self.scope = xml.findall('in')

# <unification>
# <nonterminal>expr</nonterminal>
# <src name="dcg" labels="apply,binary">
# <bgf:production>
# ...
# </bgf:production>
# </src>
# </unification>
class Unification (SrcProdModel):
def __init__(self, xml):
self.nt = xml.findtext('nonterminal')
self.parse(xml)

# <iteration>
# <label>binary</label>
# <name>expr</name>
# <separator>ops</separator>
# <src name="dcg">iterate</src>
# <src name="sdf,rsc">lassoc</src>
# </iteration>
class Iteration (SrcSimpleModel):
def __init__(self, xml):
self.label = xml.findtext('label')
self.nt = xml.findtext('name')
self.sep = xml.findtext('separator')
self.parse(xml)
236 changes: 48 additions & 188 deletions topics/convergence/tri/mbgf2xbgf.py
Expand Up @@ -4,7 +4,7 @@
sys.path.append(os.getcwd().split('slps')[0]+'slps/shared/python')
import slpsns
import xml.etree.ElementTree as ET
import BGF3,XBGF3
import BGF3,XBGF3,MBGF

namemap = {}

Expand Down Expand Up @@ -34,195 +34,55 @@ def wrapexp(exp,mod):
sys.exit(1)
else:
mbgf = ET.parse(sys.argv[1])
innum = int(sys.argv[2])
outnum = int(sys.argv[3])
inname = sys.argv[2]
outname = sys.argv[3]
xbgf = XBGF3.Sequence()
sources = {}
predicates = []
print('Reading the predicates...')
for e in mbgf.findall('*'):
if e.tag==slpsns.mbgf_('naming'):
n1 = e.findall('nonterminal')[innum-1].text
n2 = e.findall('nonterminal')[outnum-1].text
namemap[e.findtext('name')] = n2 # vice versa?
if n1==n2:
print('[MBGF] naming('+n1+','+n2+') ::= id')
else:
print('[MBGF] naming('+n1+','+n2+') ::= renameN('+n1+','+n2+')')
ren = XBGF3.Step('rename')
w = XBGF3.Wrapping('nonterminal')
w.addChild(XBGF3.Leaf('from',n1))
w.addChild(XBGF3.Leaf('to',n2))
ren.addParam(w)
xbgf.addStep(ren)
elif e.tag==slpsns.mbgf_('width'):
exp = BGF3.Expression([])
exp.parse(e.findall(slpsns.bgf_('expression'))[0])
applynamemap(exp)
e1 = e.findall('expr')[innum-1].text
e2 = e.findall('expr')[outnum-1].text
i = e.findall('in')
# namemap[e.findtext('name')] = n2 # vice versa?
yes = False
if e1==e2:
print('[MBGF] width('+str(exp)+','+e1+','+e2+') ::= id')
elif (e1,e2) in [('*','+'),('*','?'),('*','1'),('+','1'),('?','1')]:
ren = XBGF3.Step('narrow')
yes = True
elif (e2,e1) in [('*','+'),('*','?'),('*','1'),('+','1'),('?','1')]:
ren = XBGF3.Step('widen')
yes = True
else:
print('[MBGF] width error: not in narrowing relation!')
sys.exit(1)
if yes:
print('[MBGF] width('+str(exp)+','+e1+','+e2+') ::= '+ren.name+'('+wrapexp(exp,e1)+','+wrapexp(exp,e2)+')')
if e1=='1':
ren.addParam(exp)
elif e1=='+':
p = BGF3.Plus()
p.setExpr(exp)
ren.addParam(BGF3.Expression(p))
elif e1=='*':
p = BGF3.Star()
p.setExpr(exp)
ren.addParam(BGF3.Expression(p))
elif e1=='?':
p = BGF3.Optional()
p.setExpr(exp)
ren.addParam(BGF3.Expression(p))
else:
print('[MBGF] width error: unknown modifier!')
sys.exit(1)
if e2=='1':
ren.addParam(exp)
elif e2=='+':
p = BGF3.Plus()
p.setExpr(exp)
ren.addParam(BGF3.Expression(p))
elif e2=='*':
p = BGF3.Star()
p.setExpr(exp)
ren.addParam(BGF3.Expression(p))
elif e2=='?':
p = BGF3.Optional()
p.setExpr(exp)
ren.addParam(BGF3.Expression(p))
else:
print('[MBGF] width error: unknown modifier!')
sys.exit(1)
xbgf.addStep(ren)
elif e.tag==slpsns.mbgf_('unification'):
n0 = e.findtext('name')
n1 = e.findall('add')[innum-1].findtext(slpsns.bgf_('production/nonterminal'))
n2 = e.findall('add')[outnum-1].findtext(slpsns.bgf_('production/nonterminal'))
if n0 in namemap:
n3 = namemap[n0]
else:
n3 = n0
if n1:
print('[MBGF] unification('+n1+','+n0+') ::= unite('+n1+','+n3+')')
ren = XBGF3.Step('unite')
ren.addParam(XBGF3.Leaf('add',n1))
ren.addParam(XBGF3.Leaf('to',n3))
xbgf.addStep(ren)
elif n2:
print('[MBGF] unification('+n2+','+n0+') ::= split('+n3+','+n0+')')
ren = XBGF3.Step('split')
ren.addParam(XBGF3.Leaf('nonterminal',n3))
for q in e.findall('add')[outnum-1].findall(slpsns.bgf_('production')):
p = BGF3.Production()
p.parse(q)
ren.addParam(p)
attrs = e.findall('add')[outnum-1].attrib
if 'labels' in attrs:
for l in attrs['labels'].split(','):
ren.addParam(BGF3.LabelText(l))
# print('!!!',e.findall('add')[outnum-1].attrib)
# ren.addParam(XBGF3.Leaf('to',n3))
xbgf.addStep(ren)
else:
# TODO: check for the situation when both n1 and n2 are not empty
print('[MBGF] unification(∅,'+n2+') ::= id')
elif e.tag==slpsns.mbgf_('iteration'):
l = e.findtext('label')
n = e.findtext('name')
s = e.findtext('separator')
k1 = e.findall('kind')[innum-1].text
k2 = e.findall('kind')[outnum-1].text
if k1==k2:
print('[MBGF] iteration('+l+','+n+','+s+','+k1+','+k2+') ::= id')
elif k1=='iterate' and k2.endswith('assoc'):
if n in namemap:
n1 = namemap[n]
else:
n1 = n
if s in namemap:
s1 = namemap[s]
else:
s1 = s
print('[MBGF] iteration('+l+','+n+','+s+','+k1+','+k2+') ::= '+k2+'(['+l+'] '+n1+' ← '+n1+' '+s1+' '+n1+')')
ren = XBGF3.Step(k2)
p = BGF3.Production()
p.setLabel(l)
p.setNT(n1)
e = BGF3.Sequence()
e2 = BGF3.Nonterminal()
e2.setName(n1)
e.add(BGF3.Expression(e2))
if s:
e2 = BGF3.Nonterminal()
e2.setName(s1)
e.add(BGF3.Expression(e2))
e2 = BGF3.Nonterminal()
e2.setName(n1)
e.add(BGF3.Expression(e2))
p.setExpr(BGF3.Expression(e))
ren.addParam(p)
xbgf.addStep(ren)
elif k1.endswith('assoc') and k2=='iterate':
if n in namemap:
n1 = namemap[n]
else:
n1 = n
if s in namemap:
s1 = namemap[s]
else:
s1 = s
if s1:
ass = n1+' ('+s1+' '+n1+')*'
else:
ass = n1+'+'
print('[MBGF] iteration('+l+','+n+','+s+','+k1+','+k2+') ::= iterate(['+l+'] '+n1+' ← '+ass+')')
ren = XBGF3.Step('iterate')
p = BGF3.Production()
p.setLabel(l)
p.setNT(n1)
if s1:
# N (S N)*
e = BGF3.Sequence()
e2 = BGF3.Nonterminal()
e2.setName(n1)
e.add(BGF3.Expression(e2))
e3 = BGF3.Sequence()
e4 = BGF3.Nonterminal()
e4.setName(s1)
e3.add(BGF3.Expression(e4))
e3.add(BGF3.Expression(e2))
e5 = BGF3.Star()
e5.setExpr(BGF3.Expression(e3))
e.add(BGF3.Expression(e5))
else:
# N+
e = BGF3.Plus()
e2 = BGF3.Nonterminal()
e2.setName(n1)
e.setExpr(BGF3.Expression(e2))
p.setExpr(BGF3.Expression(e))
ren.addParam(p)
xbgf.addStep(ren)
else:
print('[MBGF] iteration PROBLEM')
sys.exit(1)
if e.tag=='sources':
predicates.append(MBGF.Sources(e))
# for s in e.findall('src'):
# sources[s.attrib['name']] = s.text
elif e.tag=='naming-convention':
predicates.append(MBGF.NamingConvention(e))
elif e.tag=='width':
predicates.append(MBGF.Width(e))
elif e.tag=='unification':
predicates.append(MBGF.Unification(e))
elif e.tag=='iteration':
predicates.append(MBGF.Iteration(e))
else:
print('[MBGF] Unknown command:',e.tag)
print('Predicate',e.tag,'not supported.')
# print(sources)
sys.exit(1)
# executing
print('Inferring unidirectional grammar transformations from',inname,'to',outname,'...')
pbyid = {}
unscheduled = []
for p in predicates:
# print(p.who(),'#',p.id,'@',p.depends)
if p.who() == 'Sources':
sources = p
else:
unscheduled.append(p.id)
pbyid[p.id] = p
scheduled = []
while len(unscheduled)>0:
for i in range(0,len(unscheduled)):
candidate = pbyid[unscheduled[i]]
if not(candidate.depends) or candidate.depends in scheduled:
scheduled.append(unscheduled[i])
unscheduled.remove(unscheduled[i])
break
else:
print('Failed to schedule',unscheduled)
sys.exit(2)
print('Scheduled order:',scheduled)
for id in scheduled:
pass

ET.ElementTree(xbgf.getXml()).write(sys.argv[4])
print('Success')
print('Success',predicates)

0 comments on commit 373370b

Please sign in to comment.