示例#1
0
 def parse_marker(strings: list):
     log(strings)
     assert len(strings) == 1
     name = strings[0]
     token = Token(name, MARKER)
     node = Node(token)
     stack.append(node)
示例#2
0
 def parse_string(strings: list):
     log(strings)
     assert len(strings) == 1
     name = strings[0]
     if name[0] not in ('"', "'"):
         name = "'" + name + "'"
     token = Token(name, STRING)
     node = Node(token)
     stack.append(node)
示例#3
0
 def parse_invocation(strings: list):
     log(strings)
     assert len(strings) > 1
     num_arguments = min(len(strings) - 2, list(strings).count(",") + 1)
     assert len(stack) >= num_arguments
     name = strings[0] + strings[-1]
     token = Token(name, INVOCATION)
     node = Node(token, *stack[-num_arguments:])
     del stack[-num_arguments:]
     stack.append(node)
示例#4
0
 def parse_operator(strings: list):
     log(strings)
     assert len(strings) >= 1
     assert len(stack) > 1
     name = " ".join(strings)
     token = Token(name, OPERATOR)
     right = stack.pop()
     left = stack.pop()
     node = Node(token, left, right)
     stack.append(node)
示例#5
0
 def parse_label(strings: list):
     log(strings)
     assert len(strings) == 1
     assert len(stack) == 1
     name = strings[0]
     if name == SHORT_WEAK:
         name = WEAK
     token = Token(name, LABEL)
     node = Node(token, stack.pop())
     tree.root.children.append(node)
示例#6
0
 def parse_function(strings: list):
     log(strings)
     assert len(strings) == 1
     assert len(stack) > 0
     assert stack[-1].token.name == INVOCATION
     assert stack[-1].token.type == INVOCATION
     assert len(stack[-1].children) == 2
     assert strings[0] == GET
     token = Token(GETATTR, OPERATOR)
     node = Node(token, *stack.pop().children)
     stack.append(node)
def typing(raw_tokens: Iterable[str]) -> Iterable[Token]:
    def get_type() -> str:
        if len(raw_token) > 1 and raw_token[0] in (
                '"', "'") and raw_token[0] == raw_token[-1]:
            return Types.STRING
        matches = re.match(r"%s\[(0|[1-9][0-9]*)\]" % Tokens.PARAM, raw_token)
        if matches:
            return Types.MARKER
        try:
            index = {
                name == raw_token: type
                for type, names in Tokens.instances.items() for name in names
            }
            return index[True]
        except KeyError:
            raise ValueError("Token with name '%s' can't be identified" %
                             raw_token)

    for raw_token in raw_tokens:
        yield Token(raw_token, get_type())
示例#8
0
def parse(code: str) -> Tree:
    def log(strings: list):
        # print("\t{:<15} -> {:s}".format(" ".join(strings), ":".join(str(node) for node in stack)))
        pass

    def parse_label(strings: list):
        log(strings)
        assert len(strings) == 1
        assert len(stack) == 1
        name = strings[0]
        if name == SHORT_WEAK:
            name = WEAK
        token = Token(name, LABEL)
        node = Node(token, stack.pop())
        tree.root.children.append(node)

    def parse_function(strings: list):
        log(strings)
        assert len(strings) == 1
        assert len(stack) > 0
        assert stack[-1].token.name == INVOCATION
        assert stack[-1].token.type == INVOCATION
        assert len(stack[-1].children) == 2
        assert strings[0] == GET
        token = Token(GETATTR, OPERATOR)
        node = Node(token, *stack.pop().children)
        stack.append(node)

    def parse_operator(strings: list):
        log(strings)
        assert len(strings) >= 1
        assert len(stack) > 1
        name = " ".join(strings)
        token = Token(name, OPERATOR)
        right = stack.pop()
        left = stack.pop()
        node = Node(token, left, right)
        stack.append(node)

    def parse_marker(strings: list):
        log(strings)
        assert len(strings) == 1
        name = strings[0]
        token = Token(name, MARKER)
        node = Node(token)
        stack.append(node)

    def parse_string(strings: list):
        log(strings)
        assert len(strings) == 1
        name = strings[0]
        if name[0] not in ('"', "'"):
            name = "'" + name + "'"
        token = Token(name, STRING)
        node = Node(token)
        stack.append(node)

    def parse_invocation(strings: list):
        log(strings)
        assert len(strings) > 1
        num_arguments = min(len(strings) - 2, list(strings).count(",") + 1)
        assert len(stack) >= num_arguments
        name = strings[0] + strings[-1]
        token = Token(name, INVOCATION)
        node = Node(token, *stack[-num_arguments:])
        del stack[-num_arguments:]
        stack.append(node)

    try:
        stack: List[Node] = []
        root_token = Token(ROOT, ROOT)
        root_node = Node(root_token)
        tree = Tree(root_node)
        parsers = {
            LABEL: parse_label,
            FUNCTION: parse_function,
            OPERATOR: parse_operator,
            MARKER: parse_marker,
            STRING: parse_string,
            INVOCATION: parse_invocation
        }
        parser = build(parsers)
        parser.parseString(code)
        assert len(stack) == 0
        Validator().accept(tree)
        return tree
    except AssertionError:
        raise ParseException(code, 0, 0, 0)
    except pyparsing.ParseException as ex:
        raise ParseException.value_of(code, ex)