コード例 #1
0
    def visit_Rule(self, node: Rule) -> None:
        is_loop = node.is_loop()
        is_gather = node.is_gather()
        rhs = node.flatten()
        if is_loop or is_gather:
            result_type = "asdl_seq *"
        elif node.type:
            result_type = node.type
        else:
            result_type = "void *"

        for line in str(node).splitlines():
            self.print(f"// {line}")
        if node.left_recursive and node.leader:
            self.print(f"static {result_type} {node.name}_raw(Parser *);")

        self.print(f"static {result_type}")
        self.print(f"{node.name}_rule(Parser *p)")

        if node.left_recursive and node.leader:
            self._set_up_rule_memoization(node, result_type)

        self.print("{")
        if is_loop:
            self._handle_loop_rule_body(node, rhs)
        else:
            self._handle_default_rule_body(node, rhs, result_type)
        self.print("}")
コード例 #2
0
 def visit_Rule(self, node: Rule) -> None:
     is_loop = node.is_loop()
     is_gather = node.is_gather()
     rhs = node.flatten()
     if node.left_recursive:
         if node.leader:
             self.print("@memoize_left_rec")
         else:
             # Non-leader rules in a cycle are not memoized,
             # but they must still be logged.
             self.print("@logger")
     else:
         self.print("@memoize")
     node_type = node.type or "Any"
     self.print(f"def {node.name}(self) -> Optional[{node_type}]:")
     with self.indent():
         self.print(f"# {node.name}: {rhs}")
         if node.nullable:
             self.print(f"# nullable={node.nullable}")
         self.print("mark = self.mark()")
         if is_loop:
             self.print("children = []")
         self.visit(rhs, is_loop=is_loop, is_gather=is_gather)
         if is_loop:
             self.print("return children")
         else:
             self.print("return None")
コード例 #3
0
 def visit_Rule(self, node: Rule) -> None:
     is_loop = node.is_loop()
     is_gather = node.is_gather()
     rhs = node.flatten()
     if node.left_recursive:
         if node.leader:
             self.print("@memoize_left_rec")
         else:
             # Non-leader rules in a cycle are not memoized,
             # but they must still be logged.
             self.print("@logger")
     else:
         self.print("@memoize")
     node_type = node.type or "Any"
     self.print(f"def {node.name}(self) -> Optional[{node_type}]:")
     with self.indent():
         self.print(f"# {node.name}: {rhs}")
         self.print("mark = self._mark()")
         if self.alts_uses_locations(node.rhs.alts):
             self.print("tok = self._tokenizer.peek()")
             self.print("start_lineno, start_col_offset = tok.start")
         if is_loop:
             self.print("children = []")
         self.visit(rhs, is_loop=is_loop, is_gather=is_gather)
         if is_loop:
             self.print("return children")
         else:
             self.print("return None")
コード例 #4
0
ファイル: c_generator.py プロジェクト: za/cpython
    def visit_Rule(self, node: Rule) -> None:
        is_loop = node.is_loop()
        is_gather = node.is_gather()
        rhs = node.flatten()
        if is_loop or is_gather:
            result_type = "asdl_seq *"
        elif node.type:
            result_type = node.type
        else:
            result_type = "void *"

        for line in str(node).splitlines():
            self.print(f"// {line}")
        if node.left_recursive and node.leader:
            self.print(f"static {result_type} {node.name}_raw(Parser *);")

        self.print(f"static {result_type}")
        self.print(f"{node.name}_rule(Parser *p)")

        if node.left_recursive and node.leader:
            self._set_up_rule_memoization(node, result_type)

        self.print("{")

        if node.name.endswith("without_invalid"):
            with self.indent():
                self.print("int _prev_call_invalid = p->call_invalid_rules;")
                self.print("p->call_invalid_rules = 0;")
                self.cleanup_statements.append(
                    "p->call_invalid_rules = _prev_call_invalid;")

        if is_loop:
            self._handle_loop_rule_body(node, rhs)
        else:
            self._handle_default_rule_body(node, rhs, result_type)

        if node.name.endswith("without_invalid"):
            self.cleanup_statements.pop()

        self.print("}")
コード例 #5
0
ファイル: c_generator.py プロジェクト: ssghost/pegen
    def visit_Rule(self, node: Rule) -> None:
        is_loop = node.is_loop()
        is_repeat1 = node.name.startswith("_loop1")
        memoize = not node.left_recursive
        rhs = node.flatten()
        if is_loop:
            type = "asdl_seq *"
        elif node.type:
            type = node.type
        else:
            type = "void *"

        self.print(f"// {node}")
        if node.left_recursive and node.leader:
            self.print(f"static {type} {node.name}_raw(Parser *);")

        self.print(f"static {type}")
        self.print(f"{node.name}_rule(Parser *p)")

        if node.left_recursive and node.leader:
            self.print("{")
            with self.indent():
                self.print(f"{type} res = NULL;")
                self.print(f"if (is_memoized(p, {node.name}_type, &res))")
                with self.indent():
                    self.print("return res;")
                self.print("int mark = p->mark;")
                self.print("int resmark = p->mark;")
                self.print("while (1) {")
                with self.indent():
                    self.call_with_errorcheck_return(
                        f"update_memo(p, mark, {node.name}_type, res)", "res")
                    self.print("p->mark = mark;")
                    self.print(f"void *raw = {node.name}_raw(p);")
                    self.print("if (raw == NULL || p->mark <= resmark)")
                    with self.indent():
                        self.print("break;")
                    self.print("resmark = p->mark;")
                    self.print("res = raw;")
                self.print("}")
                self.print("p->mark = resmark;")
                self.print("return res;")
            self.print("}")
            self.print(f"static {type}")
            self.print(f"{node.name}_raw(Parser *p)")

        self.print("{")
        with self.indent():
            if is_loop:
                self.print(f"void *res = NULL;")
            else:
                self.print(f"{type} res = NULL;")
            if memoize:
                self.print(f"if (is_memoized(p, {node.name}_type, &res))")
                with self.indent():
                    self.print("return res;")
            self.print("int mark = p->mark;")
            if is_loop:
                self.print("void **children = PyMem_Malloc(0);")
                self.out_of_memory_return(f"!children", "NULL")
                self.print("ssize_t n = 0;")
            self.visit(rhs,
                       is_loop=is_loop,
                       rulename=node.name if memoize else None)
            if is_loop:
                if is_repeat1:
                    self.print("if (n == 0) {")
                    with self.indent():
                        self.print("PyMem_Free(children);")
                        self.print("return NULL;")
                    self.print("}")
                self.print("asdl_seq *seq = _Py_asdl_seq_new(n, p->arena);")
                self.out_of_memory_return(f"!seq",
                                          "NULL",
                                          message=f"asdl_seq_new {node.name}")
                self.print(
                    "for (int i = 0; i < n; i++) asdl_seq_SET(seq, i, children[i]);"
                )
                self.print("PyMem_Free(children);")
                if node.name:
                    self.print(f"insert_memo(p, mark, {node.name}_type, seq);")
                self.print("return seq;")
            else:
                if self.debug:
                    self.print(
                        f'fprintf(stderr, "Fail at %d: {node.name}\\n", p->mark);'
                    )
                self.print("res = NULL;")
        if not is_loop:
            self.print("  done:")
            with self.indent():
                if memoize:
                    self.print(f"insert_memo(p, mark, {node.name}_type, res);")
                self.print("return res;")
        self.print("}")