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