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)
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_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_token(token: Token) -> (Node, List[Node]): if token.type == Types.OPERATOR: local_node = Node(token) parents.append(local_node) parents.append(local_node) elif token.type in Types.MARKER: local_node = Node(token) elif token.type == Types.STRING: local_node = Node(token) elif token.type == Types.LABEL: local_node = Node(token) parents.append(local_node) elif token.type == Types.ROOT: local_node = Node(token) num_labels = [token.type == Types.LABEL for token in tokens].count(True) parents.extend([local_node] * num_labels) else: raise Exception("Unexpected Type of token with name '%s'" % token.type) return local_node
def parse_token(token: Token) -> Node: if token.type == Types.OPERATOR: left = parse_token(next(tail)) right = parse_token(next(tail)) node = Node(token, left, right) elif token.type == Types.ROOT: children = [] child_token = next(tail, None) while child_token is not None: child = parse_token(child_token) children.append(child) child_token = next(tail, None) node = Node(token, *children) elif token.type in Types.MARKER: node = Node(token) elif token.type == Types.STRING: node = Node(token) elif token.type == Types.LABEL: node = Node(token, parse_token(next(tail))) else: raise Exception("Unexpected Type of token with name '%s'" % token.type) return node
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)