Example #1
0
 def splitword(self, n, word):
     offset = n.pos[0]
     parts = []
     children = []
     prev = None
     if hasattr(n, "parts"):
         parts = n.parts
     for part in parts:
         begin = part.pos[0]
         end = part.pos[1]
         if offset != begin:
             text = word[offset - n.pos[0]:begin - n.pos[0]]
             if prev == "CommandSubstitution" and text.startswith(")"):
                 # Workaround for bashlex bug
                 text = text[1:]
             if len(text) != 0:
                 children.append(Node(
                     "Literal",
                     [Field(
                         "value", "str",
                         self.to_leaf_value("str", text))]))
         children.append(bashlex_ast_to_ast(script, part, split_value))
         prev = children[-1].type_name
         offset = end
     if offset != n.pos[1]:
         text = word[offset - n.pos[0]:]
         if prev == "CommandSubstitution" and text.startswith(")"):
             # Workaround for bashlex bug
             text = text[1:]
         if len(text) != 0:
             children.append(Node(
                 "Literal",
                 [Field("value", "str",
                        self.to_leaf_value("str", text))]))
     return children
Example #2
0
        def generate(head: int, node_type: Optional[NodeType] = None) -> AST:
            action = self._action_sequence[head]
            if isinstance(action, GenerateToken):
                if action.kind is None:
                    assert node_type is not None
                    assert node_type.type_name is not None
                    return Leaf(node_type.type_name, action.value)
                else:
                    return Leaf(action.kind, action.value)
            elif isinstance(action, ApplyRule):
                # The head action should apply ExpandTreeRule
                rule = cast(ExpandTreeRule, action.rule)

                ast = Node(rule.parent.type_name, [])
                for (name,
                     node_type), actions in zip(rule.children,
                                                self._tree.children[head]):
                    assert node_type.type_name is not None
                    if node_type.is_variadic:
                        # Variadic field
                        ast.fields.append(Field(name, node_type.type_name, []))
                        for act in actions:
                            if isinstance(self._action_sequence[act],
                                          ApplyRule):
                                a = cast(ApplyRule, self._action_sequence[act])
                                if isinstance(a.rule, CloseVariadicFieldRule):
                                    break
                            assert isinstance(ast.fields[-1].value, list)
                            ast.fields[-1].value.append(
                                generate(act, node_type))
                    else:
                        ast.fields.append(
                            Field(name, node_type.type_name,
                                  generate(actions[0], node_type)))
                return ast
Example #3
0
 def visitfunction(self, n, name, body, parts):
     # Node(type_name="Funtion", fields={"name":Leaf(name),
     #                                   "body":[...]}
     body = [bashlex_ast_to_ast(script, x, split_value) for x in body]
     self.value = Node("Function", [
         Field("name", "str", self.to_leaf_value("str", name)),
         Field("body", "Node", body)])
     return False
Example #4
0
 def visitcompound(self, n, list, redirects):
     # Node(type_name="Compound", fileds={"list":[**list],
     #                                    "redirects":[**redicects]})
     list = [bashlex_ast_to_ast(script, x, split_value) for x in list]
     redirects = [bashlex_ast_to_ast(
         script, x, split_value) for x in redirects]
     self.value = Node("Compound", [
         Field("list", "Node", list),
         Field("redirects", "Node", redirects)])
     return False
Example #5
0
 def visitprocesssubstitution(self, n, command):
     # Node(type_name="ProcessSubstitution",
     #      fileds={"command": command, "type": Leaf(type)})
     t = script[n.pos[0]]
     self.value = Node("ProcessSubstitution",
                       [Field(
                           "command", "Node",
                           bashlex_ast_to_ast(script, command,
                                              split_value)),
                        Field("type", "str",
                              self.to_leaf_value("str", t))])
     return False
Example #6
0
 def visittilde(self, n, value):
     # Node(type_name="Tilde", fileds={"value": Leaf(value)})
     self.value = \
         Node(
             "Tilde", [Field("value", "str",
                             self.to_leaf_value("str", value))])
     return False
Example #7
0
 def visitreservedword(self, n, word):
     # Node(type_name="ReservedWord", fileds={"word": Leaf(word)})
     self.value = \
         Node("ReservedWord",
              [Field("word", "str",
                     self.to_leaf_value("str", word))])
     return False
Example #8
0
 def test_clone(self):
     a = Node("list", [
         Field("name", "literal", Leaf("str", "name")),
         Field("elems", "literal",
               [Leaf("str", "foo"), Leaf("str", "bar")])
     ])
     a1 = a.clone()
     a.name = ""
     a.type_name = ""
     a.fields[0].name = ""
     a.fields[1].value[0].type_name = ""
     assert Node("list", [
         Field("name", "literal", Leaf("str", "name")),
         Field("elems", "literal",
               [Leaf("str", "foo"), Leaf("str", "bar")])
     ]) == a1
Example #9
0
    def test_create_leaf(self):
        seq = ActionSequence.create(Leaf("str", "t0 t1"))
        assert [
            ApplyRule(
                ExpandTreeRule(NodeType(None, NodeConstraint.Node, False), [
                    ("root", NodeType(Root(), NodeConstraint.Token, False))
                ])),
            GenerateToken("str", "t0 t1")
        ] == seq.action_sequence

        seq = ActionSequence.create(
            Node(
                "value",
                [Field("name", "str", [Leaf("str", "t0"),
                                       Leaf("str", "t1")])]))
        assert [
            ApplyRule(
                ExpandTreeRule(
                    NodeType(None, NodeConstraint.Node, False),
                    [("root", NodeType(Root(), NodeConstraint.Node, False))])),
            ApplyRule(
                ExpandTreeRule(
                    NodeType("value", NodeConstraint.Node, False),
                    [("name", NodeType("str", NodeConstraint.Token, True))])),
            GenerateToken("str", "t0"),
            GenerateToken("str", "t1"),
            ApplyRule(CloseVariadicFieldRule())
        ] == seq.action_sequence
Example #10
0
 def visitcommandsubstitution(self, n, command):
     # Node(type_name="CommandSubstitution",
     #      fileds={"command": command})
     self.value = Node("CommandSubstitution",
                       [Field(
                           "command", "Node",
                           bashlex_ast_to_ast(script, command,
                                              split_value))])
     return False
Example #11
0
 def visitredirect(self, n, input, type, output, heredoc):
     # Node(type_name="Redirect", fields={"type":Leaf(type),
     #                                    "heredoc": heredoc or NoneNode
     #                                    "input": input or NoneNode
     #                                    "output": output or NoneNode
     heredoc = bashlex_ast_to_ast(script, heredoc, split_value) \
         if heredoc is not None \
         else Node("None", [])
     input = bashlex_ast_to_ast(script, input, split_value) \
         if input is not None \
         else Node("None", [])
     output = bashlex_ast_to_ast(script, output, split_value) \
         if output is not None \
         else Node("None", [])
     self.value = Node("Redirect", [
         Field("type", "str", self.to_leaf_value("str", type)),
         Field("heredoc", "Node", heredoc),
         Field("input", "Node", input),
         Field("output", "Node", output)
     ])
     return False
Example #12
0
 def test_create_node(self):
     a = Node("def", [Field("name", "literal", Leaf("str", "foo"))])
     seq = ActionSequence.create(a)
     assert [
         ApplyRule(
             ExpandTreeRule(
                 NodeType(None, NodeConstraint.Node, False),
                 [("root", NodeType(Root(), NodeConstraint.Node, False))])),
         ApplyRule(
             ExpandTreeRule(NodeType("def", NodeConstraint.Node, False), [
                 ("name", NodeType("literal", NodeConstraint.Token, False))
             ])),
         GenerateToken("str", "foo")
     ] == seq.action_sequence
Example #13
0
 def parse(self, code):
     ast = Node("Assign",
                [Field("name", "Name",
                       Node("Name", [Field("id", "str",
                                           Leaf("str", "x"))])),
                 Field("value", "expr",
                       Node("Op", [
                           Field("op", "str", Leaf("str", "+")),
                           Field("arg0", "expr",
                                 Node("Name", [Field("id", "str",
                                                     Leaf("str", "y"))])),
                           Field("arg1", "expr",
                                 Node("Number", [
                                     Field("value", "number",
                                           Leaf("number", "1"))]))]
                            ))])
     return ast
Example #14
0
    def test_generate(self):
        funcdef = ExpandTreeRule(
            NodeType("def", NodeConstraint.Node, False),
            [("name", NodeType("value", NodeConstraint.Token, True)),
             ("body", NodeType("expr", NodeConstraint.Node, True))])
        expr = ExpandTreeRule(
            NodeType("expr", NodeConstraint.Node, False),
            [("op", NodeType("value", NodeConstraint.Token, False)),
             ("arg0", NodeType("value", NodeConstraint.Token, False)),
             ("arg1", NodeType("value", NodeConstraint.Token, False))])

        action_sequence = ActionSequence()
        action_sequence.eval(ApplyRule(funcdef))
        action_sequence.eval(GenerateToken("name", "f"))
        action_sequence.eval(GenerateToken("name", "_"))
        action_sequence.eval(GenerateToken("name", "0"))
        action_sequence.eval(ApplyRule(CloseVariadicFieldRule()))
        action_sequence.eval(ApplyRule(expr))
        action_sequence.eval(GenerateToken("value", "+"))
        action_sequence.eval(GenerateToken("value", "1"))
        action_sequence.eval(GenerateToken("value", "2"))
        action_sequence.eval(ApplyRule(CloseVariadicFieldRule()))
        assert action_sequence.head is None
        assert Node("def", [
            Field("name", "value",
                  [Leaf("name", "f"),
                   Leaf("name", "_"),
                   Leaf("name", "0")]),
            Field("body", "expr", [
                Node("expr", [
                    Field("op", "value", Leaf("value", "+")),
                    Field("arg0", "value", Leaf("value", "1")),
                    Field("arg1", "value", Leaf("value", "2"))
                ])
            ])
        ]) == action_sequence.generate()
Example #15
0
 def test_create_node_with_variadic_fields(self):
     a = Node(
         "list",
         [Field("elems", "literal",
                [Node("str", []), Node("str", [])])])
     seq = ActionSequence.create(a)
     assert [
         ApplyRule(
             ExpandTreeRule(
                 NodeType(None, NodeConstraint.Node, False),
                 [("root", NodeType(Root(), NodeConstraint.Node, False))])),
         ApplyRule(
             ExpandTreeRule(NodeType("list", NodeConstraint.Node, False), [
                 ("elems", NodeType("literal", NodeConstraint.Node, True))
             ])),
         ApplyRule(
             ExpandTreeRule(NodeType("str", NodeConstraint.Node, False),
                            [])),
         ApplyRule(
             ExpandTreeRule(NodeType("str", NodeConstraint.Node, False),
                            [])),
         ApplyRule(CloseVariadicFieldRule())
     ] == seq.action_sequence
Example #16
0
 def test_node(self):
     assert Sugar.node("list", name=("literal", Leaf("str", "name"))) == \
         Node("list", [Field("name", "literal", Leaf("str", "name"))])
Example #17
0
 def test_parse_circle(self, parser):
     assert Node("Circle",
                 [Field("r", "size", Leaf("size", 1))]) == parser.parse(
                     Circle(1))
Example #18
0
 def test_parse_rectangle(self, parser):
     assert Node("Rectangle", [
         Field("w", "size", Leaf("size", 1)),
         Field("h", "size", Leaf("size", 2))
     ]) == parser.parse(Rectangle(1, 2))
Example #19
0
 def test_parse_translation(self, parser):
     assert Node("Translation", [
         Field("x", "length", Leaf("length", 1)),
         Field("y", "length", Leaf("length", 2)),
         Field("child", "CSG", Leaf("CSG", Reference(0)))
     ]) == parser.parse(Translation(1, 2, Reference(0)))
Example #20
0
 def visitcommand(self, n, parts):
     # Node(type_name="Command", fields={"parts":[...]})
     parts = [bashlex_ast_to_ast(script, x, split_value) for x in parts]
     self.value = Node("Command", [Field("parts", "Node", parts)])
     return False
Example #21
0
 def visitassignment(self, n, word):
     word = script[n.pos[0]:n.pos[1]]
     children = self.splitword(n, word)
     self.value = Node("Assign", [Field("value", "Node", children)])
     return False
Example #22
0
 def visitpipeline(self, n, parts):
     # Node(type_name="Pipeline", fields={"parts": [...]})
     parts = [bashlex_ast_to_ast(script, p, split_value) for p in parts]
     self.value = Node("Pipeline",
                       [Field("parts", "Node", parts)])
     return False
Example #23
0
 def test_parse_union(self, parser):
     assert Node("Union", [
         Field("a", "CSG", Leaf("CSG", Reference(0))),
         Field("b", "CSG", Leaf("CSG", Reference(1)))
     ]) == parser.parse(Union(Reference(0), Reference(1)))
Example #24
0
 def visitpipe(self, n, pipe):
     # Node(type_name="Pipe", fileds={"pipe": Leaf(pipe)})
     self.value = \
         Node("Pipe", [Field("pipe", "str",
                             self.to_leaf_value("str", pipe))])
     return False
Example #25
0
 def visitoperator(self, n, op):
     # Node(type_name="Operator", fileds={"op": Leaf(op)})
     self.value = \
         Node("Operator", [Field("op", "str",
                                 self.to_leaf_value("str", op))])
     return False
Example #26
0
 def test_parse_difference(self, parser):
     assert Node("Difference", [
         Field("a", "CSG", Leaf("CSG", Reference(0))),
         Field("b", "CSG", Leaf("CSG", Reference(1)))
     ]) == parser.parse(Difference(Reference(0), Reference(1)))
Example #27
0
    def create(node: AST):
        """
        Return the action sequence corresponding to this AST

        Parameters
        ----------
        node: AST

        Returns
        -------
        actionSequence
            The corresponding action sequence
        """
        def to_sequence(node: AST) -> List[Action]:
            if isinstance(node, Node):

                def to_node_type(field: Field) -> NodeType:
                    if isinstance(field.value, list):
                        if len(field.value) > 0 and \
                                isinstance(field.value[0], Leaf):
                            return NodeType(field.type_name,
                                            NodeConstraint.Token, True)
                        else:
                            return NodeType(field.type_name,
                                            NodeConstraint.Node, True)
                    else:
                        if isinstance(field.value, Leaf):
                            return NodeType(field.type_name,
                                            NodeConstraint.Token, False)
                        else:
                            return NodeType(field.type_name,
                                            NodeConstraint.Node, False)

                children = list(
                    map(lambda f: (f.name, to_node_type(f)), node.fields))

                seq: List[Action] = [
                    ApplyRule(
                        ExpandTreeRule(
                            NodeType(node.type_name, NodeConstraint.Node,
                                     False), children))
                ]
                for field in node.fields:
                    if isinstance(field.value, list):
                        for v in field.value:
                            seq.extend(to_sequence(v))
                        seq.append(ApplyRule(CloseVariadicFieldRule()))
                    else:
                        seq.extend(to_sequence(field.value))
                return seq
            elif isinstance(node, Leaf):
                node_type = node.get_type_name()
                assert not isinstance(node_type, Root)
                assert node_type is not None
                return [GenerateToken(node_type, node.value)]
            else:
                logger.critical(f"Invalid type of node: {type(node)}")
                raise RuntimeError(f"Invalid type of node: {type(node)}")

        action_sequence = ActionSequence()
        node = Node(None, [Field("root", Root(), node)])
        for action in to_sequence(node):
            action_sequence.eval(action)
        return action_sequence
Example #28
0
 def test_parse_rotation(self, parser):
     assert Node("Rotation", [
         Field("theta", "degree", Leaf("degree", 45)),
         Field("child", "CSG", Leaf("CSG", Reference(0)))
     ]) == parser.parse(Rotation(45, Reference(0)))
Example #29
0
 def parse(self, code: csgAST) -> Optional[AST]:
     if isinstance(code, Circle):
         return Node("Circle", [Field("r", "size", Leaf("size", code.r))])
     elif isinstance(code, Rectangle):
         return Node("Rectangle", [
             Field("w", "size", Leaf("size", code.w)),
             Field("h", "size", Leaf("size", code.h))
         ])
     elif isinstance(code, Translation):
         child = self.parse(code.child)
         if child is None:
             return None
         else:
             return Node("Translation", [
                 Field("x", "length", Leaf("length", code.x)),
                 Field("y", "length", Leaf("length", code.y)),
                 Field("child", "CSG", child)
             ])
     elif isinstance(code, Rotation):
         child = self.parse(code.child)
         if child is None:
             return None
         else:
             return Node("Rotation", [
                 Field("theta", "degree", Leaf("degree",
                                               code.theta_degree)),
                 Field("child", "CSG", child)
             ])
     elif isinstance(code, Union):
         a, b = self.parse(code.a), self.parse(code.b)
         if a is None or b is None:
             return None
         else:
             return Node("Union",
                         [Field("a", "CSG", a),
                          Field("b", "CSG", b)])
     elif isinstance(code, Difference):
         a, b = self.parse(code.a), self.parse(code.b)
         if a is None or b is None:
             return None
         else:
             return Node("Difference",
                         [Field("a", "CSG", a),
                          Field("b", "CSG", b)])
     elif isinstance(code, Reference):
         return Leaf("CSG", code)
     logger.warning(f"Invalid node type {code.type_name()}")
     # TODO throw exception
     return None
Example #30
0
 def visitheredoc(self, n, value):
     # Node(type_name="Heredoc", fileds={"value": Leaf(value)})
     self.value = Node(
         "Heredoc", [Field("value", "str",
                           self.to_leaf_value("str", value))])
     return False