diff --git a/shared/python/MBGF.py b/shared/python/MBGF.py index 99f1305b..2cebfe41 100755 --- a/shared/python/MBGF.py +++ b/shared/python/MBGF.py @@ -4,14 +4,26 @@ import slpsns, BGF3 import xml.etree.ElementTree as ET +cx = {} + class TopModel: + def getData(self, id): + if id in self.data.keys(): + return self.data[id] + else: + return '' def who(self): return self.__class__.__name__ def parsebasic(self, xml): + global cx if 'id' in xml.attrib: self.id = xml.attrib['id'] else: - self.id = self.who() + if self.who() in cx: + cx[self.who()] += 1 + else: + cx[self.who()] = 1 + self.id = self.who()+str(cx[self.who()]) if 'depends' in xml.attrib: self.depends = xml.attrib['depends'] else: @@ -26,6 +38,27 @@ def parse(self, xml): self.data[s] = ss.text class SrcProdModel (TopModel): + def getNTs(self,id): + nts = [] + for p in self.getProds(id): + if p.nt not in nts: + nts.append(p.nt) + return nts + def getProds(self,id): + if id in self.data.keys(): + return self.data[id][0] + else: + return [] + def getScope(self,id): + if id in self.data.keys(): + return self.data[id][1] + else: + return [] + def getData(self, id): + if id in self.data.keys(): + return '; '.join(map(str,self.data[id][0])).replace(':\n ',' ← ') + else: + return '∅' def parse(self, xml): self.parsebasic(xml) for ss in xml.findall('src'): @@ -35,7 +68,7 @@ def parse(self, xml): xp = BGF3.Production() xp.parse(p) self.data[s][0].append(xp) - self.data[s][1] = xml.findall('in') + self.data[s][1] = ss.findall('in/*') # # @@ -56,6 +89,21 @@ class NamingConvention (SrcSimpleModel): def __init__(self, xml): self.default = xml.findtext('default') self.parse(xml) + def getSpecifics(self): + return self.default + +# +# function +# function +# Function +# +class NameBind (SrcSimpleModel): + def __init__(self, xml): + self.nt = xml.findtext('name') + self.parse(xml) + def getSpecifics(self): + return self.nt + # # @@ -74,6 +122,8 @@ def __init__(self, xml): # apply namemap!!! self.parse(xml) self.scope = xml.findall('in') + def getSpecifics(self): + return str(self.expr) # # expr @@ -87,6 +137,8 @@ class Unification (SrcProdModel): def __init__(self, xml): self.nt = xml.findtext('nonterminal') self.parse(xml) + def getSpecifics(self): + return 'n('+self.nt+')' # # @@ -101,3 +153,5 @@ def __init__(self, xml): self.nt = xml.findtext('name') self.sep = xml.findtext('separator') self.parse(xml) + def getSpecifics(self): + return ', '.join(('['+self.label+']','n('+self.nt+')','n('+self.sep+')')) diff --git a/topics/convergence/tri/m2 b/topics/convergence/tri/m2 index cd66db84..aefb895a 100755 --- a/topics/convergence/tri/m2 +++ b/topics/convergence/tri/m2 @@ -1,11 +1,20 @@ #!/bin/sh +# m2 file.mbgf one two +# $0 $1 $2 $3 +./mbgf2xbgf.py $1 $2 $3 tmp.xbgf +xbgf tmp.xbgf `xpath $1 'mbgf:sequence/sources/src[@name="'$2'"]/text()' 2> /dev/null` tmp1.bgf +gdts tmp1.bgf `xpath $1 'mbgf:sequence/sources/src[@name="'$3'"]/text()' 2> /dev/null` +rm tmp.xbgf +./mbgf2xbgf.py $1 $3 $2 tmp.xbgf +xbgf tmp.xbgf `xpath $1 'mbgf:sequence/sources/src[@name="'$3'"]/text()' 2> /dev/null` tmp2.bgf +gdts tmp2.bgf `xpath $1 'mbgf:sequence/sources/src[@name="'$2'"]/text()' 2> /dev/null` # m2 file.mbgf 1 one.bgf 2 two.bgf # $0 $1 $2 $3 $4 $5 -./mbgf2xbgf.py $1 $2 $4 tmp.xbgf -xbgf tmp.xbgf $3 $3.tmp -gdts $3.tmp $5 -rm tmp.xbgf -./mbgf2xbgf.py $1 $4 $2 tmp.xbgf -xbgf tmp.xbgf $5 $5.tmp -gdts $5.tmp $3 +# ./mbgf2xbgf.py $1 $2 $4 tmp.xbgf +# xbgf tmp.xbgf $3 $3.tmp +# gdts $3.tmp $5 +# rm tmp.xbgf +# ./mbgf2xbgf.py $1 $4 $2 tmp.xbgf +# xbgf tmp.xbgf $5 $5.tmp +# gdts $5.tmp $3 diff --git a/topics/convergence/tri/mbgf2xbgf.py b/topics/convergence/tri/mbgf2xbgf.py index 8d1df352..65af2095 100755 --- a/topics/convergence/tri/mbgf2xbgf.py +++ b/topics/convergence/tri/mbgf2xbgf.py @@ -20,7 +20,7 @@ def applynamemap(e): sys.exit(1) def wrapexp(exp,mod): - if mod=='1': + if mod=='!': return str(exp) else: return str(exp)+mod @@ -47,6 +47,8 @@ def wrapexp(exp,mod): # sources[s.attrib['name']] = s.text elif e.tag=='naming-convention': predicates.append(MBGF.NamingConvention(e)) + elif e.tag=='name-bind': + predicates.append(MBGF.NameBind(e)) elif e.tag=='width': predicates.append(MBGF.Width(e)) elif e.tag=='unification': @@ -81,8 +83,198 @@ def wrapexp(exp,mod): sys.exit(2) print('Scheduled order:',scheduled) for id in scheduled: - pass - + p = pbyid[id] + print('[MBGF]',p.who(),'(',p.getSpecifics(),',',p.getData(inname),',',p.getData(outname),')', end=' ::= ') + if p.who() == 'NamingConvention': + if p.getData(inname) == p.getData(outname): + print('id') + else: + print('mutation TODO') + elif p.who() == 'NameBind': + n1 = p.getData(inname) + n2 = p.getData(outname) + namemap[p.nt] = n2 + if n1 == n2: + print('id') + else: + print('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 p.who() == 'Width': + exp = p.expr + applynamemap(exp) + e1 = p.getData(inname) + e2 = p.getData(outname) + i = p.scope # TODO + yes = False + if e1==e2: + print('id') + elif (e1,e2) in [('*','+'),('*','?'),('*','!'),('+','!'),('?','!')]: + ren = XBGF3.Step('narrow') + yes = True + elif (e2,e1) in [('*','+'),('*','?'),('*','!'),('+','!'),('?','!')]: + ren = XBGF3.Step('widen') + yes = True + else: + print('ERROR: not in narrowing relation!') + sys.exit(1) + if yes: + print(ren.name+'('+wrapexp(exp,e1)+','+wrapexp(exp,e2)+')') + if e1=='!': + 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('ERROR: unknown in modifier!') + sys.exit(1) + if e2=='!': + 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('ERROR: unknown out modifier!') + sys.exit(1) + xbgf.addStep(ren) + elif p.who() == 'Unification': + n0 = p.nt + n1 = p.getNTs(inname) + n2 = p.getNTs(outname) + if n0 in namemap: + n3 = namemap[n0] + else: + n3 = n0 + if n1: + # print('[MBGF] unification('+n1+','+n0+') ::= unite('+n1+','+n3+')') + print('unite('+n1[0]+','+n3+')') + ren = XBGF3.Step('unite') + ren.addParam(XBGF3.Leaf('add',n1[0])) + ren.addParam(XBGF3.Leaf('to',n3)) + xbgf.addStep(ren) + elif n2: + # print('[MBGF] unification('+n2+','+n0+') ::= split('+n3+','+n0+')') + print('split('+n3+','+n0+')') + ren = XBGF3.Step('split') + ren.addParam(XBGF3.Leaf('nonterminal',n3)) + for q in p.getProds(outname): + ren.addParam(q) + for l in p.getScope(outname): + ren.addParam(BGF3.LabelText(l.text)) + # 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') + print('id') + elif p.who() == 'Iteration': + l = p.label + n = p.nt + s = p.sep + k1 = p.getData(inname) + k2 = p.getData(outname) + if k1==k2: + # print('[MBGF] iteration('+l+','+n+','+s+','+k1+','+k2+') ::= id') + print('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+')') + print(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+')') + print('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('PROBLEM') + sys.exit(1) + else: + print('UNKNOWN COMMAND') ET.ElementTree(xbgf.getXml()).write(sys.argv[4]) print('Success',predicates) \ No newline at end of file diff --git a/topics/convergence/tri/test.mbgf b/topics/convergence/tri/test.mbgf index 30d70d00..108a9f11 100644 --- a/topics/convergence/tri/test.mbgf +++ b/topics/convergence/tri/test.mbgf @@ -5,12 +5,20 @@ snapshot/sdf.bgf snapshot/rascal.bgf - - l! - l! - C! - + + programprogramProgram + functionfunctionFunction + exprexprExpr + namenameName + newlinenewlineNewline + intintInt + opsopsOps + newline