From 373370b29bbbc7a8507e77f2f3a92c6904d1de6d Mon Sep 17 00:00:00 2001 From: grammarware Date: Sat, 12 May 2012 08:35:20 +0200 Subject: [PATCH] reading MBGF is done (in a rather general well-structured way) --- shared/python/MBGF.py | 103 ++++++++++++ topics/convergence/tri/mbgf2xbgf.py | 236 ++++++---------------------- topics/convergence/tri/test.mbgf | 70 +++++++++ 3 files changed, 221 insertions(+), 188 deletions(-) create mode 100755 shared/python/MBGF.py create mode 100644 topics/convergence/tri/test.mbgf diff --git a/shared/python/MBGF.py b/shared/python/MBGF.py new file mode 100755 index 00000000..99f1305b --- /dev/null +++ b/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') + +# +# +# snapshot/dcg.bgf +# snapshot/sdf.bgf +# snapshot/rascal.bgf +# +class Sources (SrcSimpleModel): + def __init__(self, xml): + self.parse(xml) + +# +# l! +# l! +# C! +# +class NamingConvention (SrcSimpleModel): + def __init__(self, xml): + self.default = xml.findtext('default') + self.parse(xml) + +# +# +# newline +# +# + +# ! +# +# function +# +# +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') + +# +# expr +# +# +# ... +# +# +# +class Unification (SrcProdModel): + def __init__(self, xml): + self.nt = xml.findtext('nonterminal') + self.parse(xml) + +# +# +# expr +# ops +# iterate +# lassoc +# +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) diff --git a/topics/convergence/tri/mbgf2xbgf.py b/topics/convergence/tri/mbgf2xbgf.py index 868dba0b..8d1df352 100755 --- a/topics/convergence/tri/mbgf2xbgf.py +++ b/topics/convergence/tri/mbgf2xbgf.py @@ -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 = {} @@ -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) \ No newline at end of file diff --git a/topics/convergence/tri/test.mbgf b/topics/convergence/tri/test.mbgf new file mode 100644 index 00000000..30d70d00 --- /dev/null +++ b/topics/convergence/tri/test.mbgf @@ -0,0 +1,70 @@ + + + + snapshot/dcg.bgf + snapshot/sdf.bgf + snapshot/rascal.bgf + + + l! + l! + C! + + + + + newline + + + + ! + + function + + + + expr + + + + atom + + int + + + + + atom + + name + + + + atom + + + + ( + + + expr + + + ) + + + + + + + + + + + + + expr + ops + iterate + lassoc + +