def evaluateArguments(self, this): argumentsAST = this.argumentsAST if not argumentsAST or not argumentsAST.getFirstChild(): # return immediately if missing tree or no actual args return # Evaluate args in the context of the enclosing template, but we # need the predefined args like 'it', 'attr', and 'i' to be # available as well so we put a dummy ST between the enclosing # context and the embedded context. The dummy has the predefined # context as does the embedded. enclosing = this.enclosingInstance argContextST = stringtemplate3.StringTemplate(group=this.group, template="") argContextST.name = '<invoke ' + this.name + ' arg context>' argContextST.enclosingInstance = enclosing argContextST.argumentContext = this.argumentContext eval_ = ActionEvaluator.Walker() eval_.initialize(argContextST, self, None) #sys.stderr.write('eval args: ' + argumentsAST.toStringList() + '\n') #sys.stderr.write('ctx is ' + this.getArgumentContext()) try: # using any initial argument context (such as when obj is set), # evaluate the arg list like bold(item=obj). Since we pass # in any existing arg context, that context gets filled with # new values. With bold(item=obj), context becomes: #:[obj=...],[item=...]}. ac = eval_.argList(argumentsAST, this, this.argumentContext) this.argumentContext = ac except antlr.RecognitionException, re: this.error('can\'t evaluate tree: ' + argumentsAST.toStringList(), re)
def testNone(self): """toDOT()""" treeST = stringtemplate3.StringTemplate( template=( "digraph {\n" + " $nodes$\n" + " $edges$\n" + "}\n") ) edgeST = stringtemplate3.StringTemplate( template="$parent$ -> $child$\n" ) tree = self.wiz.create("(A B (B C C) (B (C D D)))") st = toDOT(tree, self.adaptor, treeST, edgeST) result = st.toString() expected = textwrap.dedent( '''\ digraph { n0 [label="A"]; n1 [label="B"]; n2 [label="B"]; n3 [label="C"]; n4 [label="C"]; n5 [label="B"]; n6 [label="C"]; n7 [label="D"]; n8 [label="D"]; n0 -> n1 n0 -> n2 n2 -> n3 n2 -> n4 n0 -> n5 n5 -> n6 n6 -> n7 n6 -> n8 } ''' ) self.assertEqual(result, expected)
def arg(self, st): name = None s = None bs = None defaultValue = None try: ## for error handling pass name = self.LT(1) self.match(ID) if (self.LA(1) == ASSIGN) and (self.LA(2) == STRING): pass self.match(ASSIGN) s = self.LT(1) self.match(STRING) defaultValue = stringtemplate3.StringTemplate( template="$_val_$") defaultValue["_val_"] = s.getText() defaultValue.defineFormalArgument("_val_") defaultValue.name = ("<" + st.name + "'s arg " + name.getText() + " default value subtemplate>") elif (self.LA(1) == ASSIGN) and (self.LA(2) == ANONYMOUS_TEMPLATE): pass self.match(ASSIGN) bs = self.LT(1) self.match(ANONYMOUS_TEMPLATE) defaultValue = stringtemplate3.StringTemplate( group=st.group, template=bs.getText()) defaultValue.name = ("<" + st.name + "'s arg " + name.getText() + " default value subtemplate>") elif (self.LA(1) == COMMA or self.LA(1) == RPAREN): pass else: raise antlr.NoViableAltException(self.LT(1), self.getFilename()) st.defineFormalArgument(name.getText(), defaultValue) except antlr.RecognitionException, ex: self.reportError(ex) self.consume() self.consumeUntil(_tokenSet_3)
def keyValue(self): value = None s1 = None s2 = None k = None try: ## for error handling la1 = self.LA(1) if False: pass elif la1 and la1 in [STRING]: pass s1 = self.LT(1) self.match(STRING) value = stringtemplate3.StringTemplate(group=self.group_, template=s1.getText()) elif la1 and la1 in [BIGSTRING]: pass s2 = self.LT(1) self.match(BIGSTRING) value = stringtemplate3.StringTemplate(group=self.group_, template=s2.getText()) elif la1 and la1 in [ID]: pass k = self.LT(1) self.match(ID) if not k.getText() == "key": raise antlr.SemanticException(" k.getText() == \"key\" ") value = stringtemplate3.language.ASTExpr.MAP_KEY_VALUE elif la1 and la1 in [COMMA, RBRACK]: pass else: raise antlr.NoViableAltException(self.LT(1), self.getFilename()) except antlr.RecognitionException, ex: self.reportError(ex) self.consume() self.consumeUntil(_tokenSet_5)
class DOTTreeGenerator(object): """ A utility class to generate DOT diagrams (graphviz) from arbitrary trees. You can pass in your own templates and can pass in any kind of tree or use Tree interface method. """ _treeST = stringtemplate3.StringTemplate(template=( "digraph {\n" + " ordering=out;\n" + " ranksep=.4;\n" + " node [shape=plaintext, fixedsize=true, fontsize=11, fontname=\"Courier\",\n" + " width=.25, height=.25];\n" + " edge [arrowsize=.5]\n" + " $nodes$\n" + " $edges$\n" + "}\n")) _nodeST = stringtemplate3.StringTemplate( template="$name$ [label=\"$text$\"];\n") _edgeST = stringtemplate3.StringTemplate( template="$parent$ -> $child$ // \"$parentText$\" -> \"$childText$\"\n" ) def __init__(self): ## Track node to number mapping so we can get proper node name back self.nodeToNumberMap = {} ## Track node number so we can get unique node names self.nodeNumber = 0 def toDOT(self, tree, adaptor=None, treeST=_treeST, edgeST=_edgeST): if adaptor is None: adaptor = CommonTreeAdaptor() treeST = treeST.getInstanceOf() self.nodeNumber = 0 self.toDOTDefineNodes(tree, adaptor, treeST) self.nodeNumber = 0 self.toDOTDefineEdges(tree, adaptor, treeST, edgeST) return treeST def toDOTDefineNodes(self, tree, adaptor, treeST, knownNodes=None): if knownNodes is None: knownNodes = set() if tree is None: return n = adaptor.getChildCount(tree) if n == 0: # must have already dumped as child from previous # invocation; do nothing return # define parent node number = self.getNodeNumber(tree) if number not in knownNodes: parentNodeST = self.getNodeST(adaptor, tree) treeST.setAttribute("nodes", parentNodeST) knownNodes.add(number) # for each child, do a "<unique-name> [label=text]" node def for i in range(n): child = adaptor.getChild(tree, i) number = self.getNodeNumber(child) if number not in knownNodes: nodeST = self.getNodeST(adaptor, child) treeST.setAttribute("nodes", nodeST) knownNodes.add(number) self.toDOTDefineNodes(child, adaptor, treeST, knownNodes) def toDOTDefineEdges(self, tree, adaptor, treeST, edgeST): if tree is None: return n = adaptor.getChildCount(tree) if n == 0: # must have already dumped as child from previous # invocation; do nothing return parentName = "n%d" % self.getNodeNumber(tree) # for each child, do a parent -> child edge using unique node names parentText = adaptor.getText(tree) for i in range(n): child = adaptor.getChild(tree, i) childText = adaptor.getText(child) childName = "n%d" % self.getNodeNumber(child) edgeST = edgeST.getInstanceOf() edgeST.setAttribute("parent", parentName) edgeST.setAttribute("child", childName) edgeST.setAttribute("parentText", parentText) edgeST.setAttribute("childText", childText) treeST.setAttribute("edges", edgeST) self.toDOTDefineEdges(child, adaptor, treeST, edgeST) def getNodeST(self, adaptor, t): text = adaptor.getText(t) nodeST = self._nodeST.getInstanceOf() uniqueName = "n%d" % self.getNodeNumber(t) nodeST.setAttribute("name", uniqueName) if text is not None: text = text.replace('"', r'\"') nodeST.setAttribute("text", text) return nodeST def getNodeNumber(self, t): try: return self.nodeToNumberMap[t] except KeyError: self.nodeToNumberMap[t] = self.nodeNumber self.nodeNumber += 1 return self.nodeNumber - 1
def template(self, g): scope = None region = None name = None t = None bt = None alias = None target = None formalArgs = {} st = None ignore = False templateName = None line = self.LT(1).getLine() try: ## for error handling if (self.LA(1) == ID or self.LA(1) == AT) and (self.LA(2) == ID or self.LA(2) == LPAREN): pass la1 = self.LA(1) if False: pass elif la1 and la1 in [AT]: pass self.match(AT) scope = self.LT(1) self.match(ID) self.match(DOT) region = self.LT(1) self.match(ID) templateName = g.getMangledRegionName( scope.getText(), region.getText()) if g.isDefinedInThisGroup(templateName): g.error("group " + g.name + " line " + str(line) + ": redefinition of template region: @" + scope.getText() + "." + region.getText()) st = stringtemplate3.StringTemplate( ) # create bogus template to fill in else: err = False # @template.region() ::= "..." scopeST = g.lookupTemplate(scope.getText()) if scopeST is None: g.error( "group " + g.name + " line " + str(line) + ": reference to region within undefined template: " + scope.getText()) err = True if not scopeST.containsRegionName(region.getText()): g.error("group " + g.name + " line " + str(line) + ": template " + scope.getText() + " has no region called " + region.getText()) err = True if err: st = stringtemplate3.StringTemplate() else: st = g.defineRegionTemplate( scope.getText(), region.getText(), None, stringtemplate3.REGION_EXPLICIT) elif la1 and la1 in [ID]: pass name = self.LT(1) self.match(ID) templateName = name.getText() if g.isDefinedInThisGroup(templateName): g.error("redefinition of template: " + templateName) # create bogus template to fill in st = stringtemplate3.StringTemplate() else: st = g.defineTemplate(templateName, None) else: raise antlr.NoViableAltException(self.LT(1), self.getFilename()) if st is not None: st.groupFileLine = line self.match(LPAREN) la1 = self.LA(1) if False: pass elif la1 and la1 in [ID]: pass self.args(st) elif la1 and la1 in [RPAREN]: pass st.defineEmptyFormalArgumentList() else: raise antlr.NoViableAltException(self.LT(1), self.getFilename()) self.match(RPAREN) self.match(DEFINED_TO_BE) la1 = self.LA(1) if False: pass elif la1 and la1 in [STRING]: pass t = self.LT(1) self.match(STRING) st.template = t.getText() elif la1 and la1 in [BIGSTRING]: pass bt = self.LT(1) self.match(BIGSTRING) st.template = bt.getText() else: raise antlr.NoViableAltException(self.LT(1), self.getFilename()) elif (self.LA(1) == ID) and (self.LA(2) == DEFINED_TO_BE): pass alias = self.LT(1) self.match(ID) self.match(DEFINED_TO_BE) target = self.LT(1) self.match(ID) g.defineTemplateAlias(alias.getText(), target.getText()) else: raise antlr.NoViableAltException(self.LT(1), self.getFilename()) except antlr.RecognitionException, ex: self.reportError(ex) self.consume() self.consumeUntil(_tokenSet_1)
def action(self, this): a = None i = None ei = None rr = None rd = None try: ## for error handling la1 = self.LA(1) if False: pass elif la1 and la1 in [ACTION]: pass a = self.LT(1) self.match(ACTION) indent = a.indentation c = this.parseAction(a.getText()) c.indentation = indent this.addChunk(c) elif la1 and la1 in [IF]: pass i = self.LT(1) self.match(IF) c = this.parseAction(i.getText()) # create and precompile the subtemplate subtemplate = stringtemplate3.StringTemplate(group=this.group) subtemplate.enclosingInstance = this subtemplate.name = i.getText() + "_subtemplate" this.addChunk(c) self.template(subtemplate) if c: c.subtemplate = subtemplate while True: if (self.LA(1) == ELSEIF): pass ei = self.LT(1) self.match(ELSEIF) ec = this.parseAction(ei.getText()) # create and precompile the subtemplate elseIfSubtemplate = stringtemplate3.StringTemplate( group=this.group) elseIfSubtemplate.enclosingInstance = this elseIfSubtemplate.name = ei.getText() + "_subtemplate" self.template(elseIfSubtemplate) if c is not None: c.addElseIfSubtemplate(ec, elseIfSubtemplate) else: break la1 = self.LA(1) if False: pass elif la1 and la1 in [ELSE]: pass self.match(ELSE) # create and precompile the subtemplate elseSubtemplate = stringtemplate3.StringTemplate( group=this.group) elseSubtemplate.enclosingInstance = this elseSubtemplate.name = "else_subtemplate" self.template(elseSubtemplate) if c: c.elseSubtemplate = elseSubtemplate elif la1 and la1 in [ENDIF]: pass else: raise antlr.NoViableAltException(self.LT(1), self.getFilename()) self.match(ENDIF) elif la1 and la1 in [REGION_REF]: pass rr = self.LT(1) self.match(REGION_REF) # define implicit template and # convert <@r()> to <region__enclosingTemplate__r()> regionName = rr.getText() mangledRef = None err = False # watch out for <@super.r()>; that does NOT def implicit region # convert to <super.region__enclosingTemplate__r()> if regionName.startswith("super."): #System.out.println("super region ref "+regionName); regionRef = regionName[len("super."):len(regionName)] templateScope = this.group.getUnMangledTemplateName( this.name) scopeST = this.group.lookupTemplate(templateScope) if scopeST is None: this.group.error( "reference to region within undefined template: " + templateScope) err = True if not scopeST.containsRegionName(regionRef): this.group.error("template " + templateScope + " has no region called " + regionRef) err = True else: mangledRef = this.group.getMangledRegionName( templateScope, regionRef) mangledRef = "super." + mangledRef else: regionST = this.group.defineImplicitRegionTemplate( this, regionName) mangledRef = regionST.name if not err: # treat as regular action: mangled template include indent = rr.indentation c = this.parseAction(mangledRef + "()") c.indentation = indent this.addChunk(c) elif la1 and la1 in [REGION_DEF]: pass rd = self.LT(1) self.match(REGION_DEF) combinedNameTemplateStr = rd.getText() indexOfDefSymbol = combinedNameTemplateStr.find("::=") if indexOfDefSymbol >= 1: regionName = combinedNameTemplateStr[0:indexOfDefSymbol] template = combinedNameTemplateStr[ indexOfDefSymbol + 3:len(combinedNameTemplateStr)] regionST = this.group.defineRegionTemplate( this, regionName, template, stringtemplate3.REGION_EMBEDDED) # treat as regular action: mangled template include indent = rd.indentation c = this.parseAction(regionST.name + "()") c.indentation = indent this.addChunk(c) else: this.error("embedded region definition screwed up") else: raise antlr.NoViableAltException(self.LT(1), self.getFilename()) except antlr.RecognitionException, ex: self.reportError(ex) self.consume() self.consumeUntil(_tokenSet_1)