def parse(self, ee): self.name = ee.tag for e in e.findall(slpsns.bgf_('*')): if e.tag == 'expression': ne = BGF3.Expression() elif e.tag == 'production': ne = BGF3.Production() else: print('Unknown parameter of type', e.tag) ne = None ne.parse(e) self.params.append(ne)
def projectSymbols(xs,ss): if xs.who() == 'Sequence': e = BGF3.Sequence() for x in xs.data: # TODO: now works only for nonterminals if x.wrapped.who() == 'Nonterminal' and x.wrapped.data in ss: m = BGF3.Marked() m.setExpr(BGF3.Expression(x)) e.add(m) else: e.add(x) return e else: print('projectSymbols not implemented for',xs.who()) print('■') sys.exit(1)
def renameNinExpr(namemap,expr): if expr.who() == 'Sequence': e = BGF3.Sequence() for el in expr.data: e.add(BGF3.Expression(renameNinExpr(namemap,el.wrapped))) return e elif expr.who() == 'Nonterminal': e = BGF3.Nonterminal() if expr.data in namemap: e.setName(namemap[expr.data]) else: e.setName(expr.data) return e else: print('Unfinished implementation of renameNin for',expr.who()) print('■') sys.exit(1)
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()
def checkCandidates(indent,key,nt,candidates,masterprods): good = [] for c in candidates: myprods = bgf.getProdsOfN(c) if myprods: print(indent,'√',c,'is defined as',ppseplist(';',map(lambda x:str(x.expr),myprods))) elif c in ['string','int']: # value => compose a fake rule that "defines" value as value # the condition above is hacky (what if there is a nonterminal called "string" or "int"?) print(indent,'√',c,'is a built-in') p = BGF3.Production() p.setNT(c) v = BGF3.Value() v.data = c p.setExpr(BGF3.Expression(v)) else: print(indent,'√',c,'is undefined') if masterprods: print(indent,' ⇒ not a good candidate because its master counterpart is defined') continue else: print(indent,' ⇒ good candidate because both are undefined') good.append(c) continue #print('###my prods:',ppseplist(';',map(lambda x:str(x.expr),myprods))) #print('###masterprods:',ppseplist(';',map(lambda x:str(x.expr),masterprods))) if masterprods: if len(myprods)==1 and len(masterprods)==1: if sameThing(key,myprods[0].expr,None,masterprods[0].expr): print(indent,' ⇒ good candidate because both definitions are identical') good.append(c) elif moreLiberal(myprods[0],masterprods[0]): print(indent,' ⇒ good candidate because it is defined more liberally') good.append(c) else: print(indent,' ⇒ not a good candidate because two definitions do not match') else: cx1 = cx2 = 0 for p in masterprods: for q in myprods: if sameThing(key,q.expr,None,p.expr): cx1 += 1 elif moreLiberal(q,p): cx2 += 1 if cx1 and cx2: print(indent,' ⇒ good candidate because at least',cx1,'rules are identical to and at least',cx2,' rules are more liberal than the master\'s') good.append(c) elif cx1: print(indent,' ⇒ good candidate because at least',cx1,'rules are identical to the master\'s') good.append(c) elif cx2: print(indent,' ⇒ good candidate because at least',cx2,' rules are more liberal than the master\'s') good.append(c) else: print(indent,' ⇒ not a good candidate because multiple unrelated rules are found') elif not nt and len(myprods) == 1 and myprods[0].expr.wrapped.who() == 'Value': # TODO: check this code print(indent,' ⇒ good candidate because',c,'is defined as a built-in') good.append(c) else: print(indent,' ⇒ not a good candidate because',nt,'is undefined') return good
print(' ⇒',masterprods[0].expr.wrapped.data,'maps to',myprods[0].expr.wrapped.data,'in',key) nnt = str(masterprods[0].expr.wrapped.data) bind(key,nnt,str(myprods[0].expr.wrapped.data)) #renameNin(str(myprods[0].expr.wrapped.data),nnt,key) if nnt not in ntsdone and nnt not in nts2go and nnt not in ['string','int']: nts2go.append(nnt) elif moreLiberal(myprods[0],masterprods[0]): print(' ☯ Disregarding more liberal specification,') print(' ⇒',masterprods[0].expr.wrapped.data,'maps to',myprods[0].expr.wrapped.data) bind(key,str(masterprods[0].expr.wrapped.data),str(myprods[0].expr.wrapped.data)) #renameNin(str(myprods[0].expr.wrapped.data),str(masterprods[0].expr.wrapped.data),key) else: match(' ',key,dicts[key][nt],myprods[0].expr.wrapped,nt,masterprods[0].expr.wrapped) else: # undefined in the master grammar if sameThing(key,myprods[0].expr,None,BGF3.Expression(BGF3.Empty())): print(' ☯ Strictly speaking, undefined is φ, so') print(' ⇒ None maps to',myprods[0].expr.wrapped.data,'in',key) print('■TODO') sys.exit(1) elif sameThing(key,myprods[0].expr,None,BGF3.Expression(BGF3.Epsilon())): # HACK! # bind(key,None,nt) print(' ☯ Considering undefined as ε,') print(' ⇒ Trivial match in',key) step = CBGF3.Step('undefine-define') p = BGF3.Production() p.nt = nt p.expr = myprods[0].expr p.label = myprods[0].label step.addParam(p)