示例#1
0
    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)
示例#3
0
    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)
示例#4
0
    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)
示例#5
0
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
示例#6
0
    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)
示例#7
0
    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)