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(' ✗ Also disregarding unused',nt,'in',key) step = CBGF3.Step('eliminate-introduce') step.params.extend(bgfs[key].getProdsOfN(nt)) cbgfs[key].addFirstStep(step) print('√ Writing ΞBGF files…') for key in cbgfs.keys(): # print('All real NTs:',allrealnts[key]) for valuetype in ('string','int'): if valuetype in allnts and valuetype not in alllocalnts[key]: # print(list(map(lambda x:x.text,bgfs[key].getXml().findall(".//nonterminal")))) if valuetype not in map(lambda x:x.text,bgfs[key].getXml().findall(".//nonterminal")): print(' & Built-in sort',valuetype,'usage detected in',key) step = CBGF3.Step('define-undefine') p = BGF3.Production() p.nt = valuetype v = BGF3.Value() v.data = valuetype p.expr = BGF3.Expression(v) step.addParam(p) cbgfs[key].addStep(step) step = CBGF3.Step('inline-extract') step.addParam(p) cbgfs[key].addStep(step) # print(alllocalnts[key]) # if valuetype in alllocalnts[key] and used: # print(list(map(lambda x:x.text,bgfs[key].getXml().findall(".//nonterminal")))) # if valuetype in map(lambda x:x.text,bgfs[key].getXml().findall(".//nonterminal")): # print('yES') # else: # print(' & Built-in sort',valuetype,'usage detected in the master grammar',key) # step = CBGF3.Step('define-undefine')