mirror of https://github.com/python/cpython
Fix typing problems reported by mypy in pegen (GH-20297)
This commit is contained in:
parent
2e76820a50
commit
d10fef35c6
|
@ -1,5 +1,5 @@
|
||||||
import ast
|
import ast
|
||||||
from dataclasses import dataclass
|
from dataclasses import field, dataclass
|
||||||
import re
|
import re
|
||||||
from typing import Any, Dict, IO, Optional, List, Text, Tuple, Set
|
from typing import Any, Dict, IO, Optional, List, Text, Tuple, Set
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
@ -25,6 +25,7 @@ from pegen.grammar import (
|
||||||
)
|
)
|
||||||
from pegen.parser_generator import ParserGenerator
|
from pegen.parser_generator import ParserGenerator
|
||||||
|
|
||||||
|
|
||||||
EXTENSION_PREFIX = """\
|
EXTENSION_PREFIX = """\
|
||||||
#include "pegen.h"
|
#include "pegen.h"
|
||||||
|
|
||||||
|
@ -63,7 +64,7 @@ BASE_NODETYPES = {
|
||||||
@dataclass
|
@dataclass
|
||||||
class FunctionCall:
|
class FunctionCall:
|
||||||
function: str
|
function: str
|
||||||
arguments: Optional[List[Any]] = None
|
arguments: List[Any] = field(default_factory=list)
|
||||||
assigned_variable: Optional[str] = None
|
assigned_variable: Optional[str] = None
|
||||||
return_type: Optional[str] = None
|
return_type: Optional[str] = None
|
||||||
nodetype: Optional[NodeTypes] = None
|
nodetype: Optional[NodeTypes] = None
|
||||||
|
@ -94,7 +95,7 @@ class CCallMakerVisitor(GrammarVisitor):
|
||||||
self.gen = parser_generator
|
self.gen = parser_generator
|
||||||
self.exact_tokens = exact_tokens
|
self.exact_tokens = exact_tokens
|
||||||
self.non_exact_tokens = non_exact_tokens
|
self.non_exact_tokens = non_exact_tokens
|
||||||
self.cache: Dict[Any, Any] = {}
|
self.cache: Dict[Any, FunctionCall] = {}
|
||||||
self.keyword_cache: Dict[str, int] = {}
|
self.keyword_cache: Dict[str, int] = {}
|
||||||
|
|
||||||
def keyword_helper(self, keyword: str) -> FunctionCall:
|
def keyword_helper(self, keyword: str) -> FunctionCall:
|
||||||
|
@ -171,7 +172,7 @@ class CCallMakerVisitor(GrammarVisitor):
|
||||||
if node in self.cache:
|
if node in self.cache:
|
||||||
return self.cache[node]
|
return self.cache[node]
|
||||||
if can_we_inline(node):
|
if can_we_inline(node):
|
||||||
self.cache[node] = self.visit(node.alts[0].items[0])
|
self.cache[node] = self.generate_call(node.alts[0].items[0])
|
||||||
else:
|
else:
|
||||||
name = self.gen.name_node(node)
|
name = self.gen.name_node(node)
|
||||||
self.cache[node] = FunctionCall(
|
self.cache[node] = FunctionCall(
|
||||||
|
@ -183,13 +184,13 @@ class CCallMakerVisitor(GrammarVisitor):
|
||||||
return self.cache[node]
|
return self.cache[node]
|
||||||
|
|
||||||
def visit_NamedItem(self, node: NamedItem) -> FunctionCall:
|
def visit_NamedItem(self, node: NamedItem) -> FunctionCall:
|
||||||
call = self.visit(node.item)
|
call = self.generate_call(node.item)
|
||||||
if node.name:
|
if node.name:
|
||||||
call.assigned_variable = node.name
|
call.assigned_variable = node.name
|
||||||
return call
|
return call
|
||||||
|
|
||||||
def lookahead_call_helper(self, node: Lookahead, positive: int) -> FunctionCall:
|
def lookahead_call_helper(self, node: Lookahead, positive: int) -> FunctionCall:
|
||||||
call = self.visit(node.node)
|
call = self.generate_call(node.node)
|
||||||
if call.nodetype == NodeTypes.NAME_TOKEN:
|
if call.nodetype == NodeTypes.NAME_TOKEN:
|
||||||
return FunctionCall(
|
return FunctionCall(
|
||||||
function=f"_PyPegen_lookahead_with_name",
|
function=f"_PyPegen_lookahead_with_name",
|
||||||
|
@ -217,7 +218,7 @@ class CCallMakerVisitor(GrammarVisitor):
|
||||||
return self.lookahead_call_helper(node, 0)
|
return self.lookahead_call_helper(node, 0)
|
||||||
|
|
||||||
def visit_Opt(self, node: Opt) -> FunctionCall:
|
def visit_Opt(self, node: Opt) -> FunctionCall:
|
||||||
call = self.visit(node.node)
|
call = self.generate_call(node.node)
|
||||||
return FunctionCall(
|
return FunctionCall(
|
||||||
assigned_variable="_opt_var",
|
assigned_variable="_opt_var",
|
||||||
function=call.function,
|
function=call.function,
|
||||||
|
@ -266,7 +267,7 @@ class CCallMakerVisitor(GrammarVisitor):
|
||||||
return self.cache[node]
|
return self.cache[node]
|
||||||
|
|
||||||
def visit_Group(self, node: Group) -> FunctionCall:
|
def visit_Group(self, node: Group) -> FunctionCall:
|
||||||
return self.visit(node.rhs)
|
return self.generate_call(node.rhs)
|
||||||
|
|
||||||
def visit_Cut(self, node: Cut) -> FunctionCall:
|
def visit_Cut(self, node: Cut) -> FunctionCall:
|
||||||
return FunctionCall(
|
return FunctionCall(
|
||||||
|
@ -276,6 +277,9 @@ class CCallMakerVisitor(GrammarVisitor):
|
||||||
nodetype=NodeTypes.CUT_OPERATOR,
|
nodetype=NodeTypes.CUT_OPERATOR,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def generate_call(self, node: Any) -> FunctionCall:
|
||||||
|
return super().visit(node)
|
||||||
|
|
||||||
|
|
||||||
class CParserGenerator(ParserGenerator, GrammarVisitor):
|
class CParserGenerator(ParserGenerator, GrammarVisitor):
|
||||||
def __init__(
|
def __init__(
|
||||||
|
@ -317,17 +321,13 @@ class CParserGenerator(ParserGenerator, GrammarVisitor):
|
||||||
self.print(f"goto {goto_target};")
|
self.print(f"goto {goto_target};")
|
||||||
self.print(f"}}")
|
self.print(f"}}")
|
||||||
|
|
||||||
def out_of_memory_return(
|
def out_of_memory_return(self, expr: str, cleanup_code: Optional[str] = None,) -> None:
|
||||||
self,
|
|
||||||
expr: str,
|
|
||||||
cleanup_code: Optional[str] = None,
|
|
||||||
) -> None:
|
|
||||||
self.print(f"if ({expr}) {{")
|
self.print(f"if ({expr}) {{")
|
||||||
with self.indent():
|
with self.indent():
|
||||||
if cleanup_code is not None:
|
if cleanup_code is not None:
|
||||||
self.print(cleanup_code)
|
self.print(cleanup_code)
|
||||||
self.print("p->error_indicator = 1;")
|
self.print("p->error_indicator = 1;")
|
||||||
self.print("PyErr_NoMemory();");
|
self.print("PyErr_NoMemory();")
|
||||||
self.print("return NULL;")
|
self.print("return NULL;")
|
||||||
self.print(f"}}")
|
self.print(f"}}")
|
||||||
|
|
||||||
|
@ -484,10 +484,7 @@ class CParserGenerator(ParserGenerator, GrammarVisitor):
|
||||||
if any(alt.action and "EXTRA" in alt.action for alt in rhs.alts):
|
if any(alt.action and "EXTRA" in alt.action for alt in rhs.alts):
|
||||||
self._set_up_token_start_metadata_extraction()
|
self._set_up_token_start_metadata_extraction()
|
||||||
self.visit(
|
self.visit(
|
||||||
rhs,
|
rhs, is_loop=False, is_gather=node.is_gather(), rulename=node.name,
|
||||||
is_loop=False,
|
|
||||||
is_gather=node.is_gather(),
|
|
||||||
rulename=node.name,
|
|
||||||
)
|
)
|
||||||
if self.debug:
|
if self.debug:
|
||||||
self.print('fprintf(stderr, "Fail at %d: {node.name}\\n", p->mark);')
|
self.print('fprintf(stderr, "Fail at %d: {node.name}\\n", p->mark);')
|
||||||
|
@ -518,10 +515,7 @@ class CParserGenerator(ParserGenerator, GrammarVisitor):
|
||||||
if any(alt.action and "EXTRA" in alt.action for alt in rhs.alts):
|
if any(alt.action and "EXTRA" in alt.action for alt in rhs.alts):
|
||||||
self._set_up_token_start_metadata_extraction()
|
self._set_up_token_start_metadata_extraction()
|
||||||
self.visit(
|
self.visit(
|
||||||
rhs,
|
rhs, is_loop=True, is_gather=node.is_gather(), rulename=node.name,
|
||||||
is_loop=True,
|
|
||||||
is_gather=node.is_gather(),
|
|
||||||
rulename=node.name,
|
|
||||||
)
|
)
|
||||||
if is_repeat1:
|
if is_repeat1:
|
||||||
self.print("if (_n == 0 || p->error_indicator) {")
|
self.print("if (_n == 0 || p->error_indicator) {")
|
||||||
|
@ -567,7 +561,7 @@ class CParserGenerator(ParserGenerator, GrammarVisitor):
|
||||||
self.print("}")
|
self.print("}")
|
||||||
|
|
||||||
def visit_NamedItem(self, node: NamedItem) -> None:
|
def visit_NamedItem(self, node: NamedItem) -> None:
|
||||||
call = self.callmakervisitor.visit(node)
|
call = self.callmakervisitor.generate_call(node)
|
||||||
if call.assigned_variable:
|
if call.assigned_variable:
|
||||||
call.assigned_variable = self.dedupe(call.assigned_variable)
|
call.assigned_variable = self.dedupe(call.assigned_variable)
|
||||||
self.print(call)
|
self.print(call)
|
||||||
|
@ -674,7 +668,9 @@ class CParserGenerator(ParserGenerator, GrammarVisitor):
|
||||||
self.print("if (_n == _children_capacity) {")
|
self.print("if (_n == _children_capacity) {")
|
||||||
with self.indent():
|
with self.indent():
|
||||||
self.print("_children_capacity *= 2;")
|
self.print("_children_capacity *= 2;")
|
||||||
self.print("void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));")
|
self.print(
|
||||||
|
"void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));"
|
||||||
|
)
|
||||||
self.out_of_memory_return(f"!_new_children")
|
self.out_of_memory_return(f"!_new_children")
|
||||||
self.print("_children = _new_children;")
|
self.print("_children = _new_children;")
|
||||||
self.print("}")
|
self.print("}")
|
||||||
|
@ -721,7 +717,7 @@ class CParserGenerator(ParserGenerator, GrammarVisitor):
|
||||||
return types
|
return types
|
||||||
|
|
||||||
def add_var(self, node: NamedItem) -> Tuple[Optional[str], Optional[str]]:
|
def add_var(self, node: NamedItem) -> Tuple[Optional[str], Optional[str]]:
|
||||||
call = self.callmakervisitor.visit(node.item)
|
call = self.callmakervisitor.generate_call(node.item)
|
||||||
name = node.name if node.name else call.assigned_variable
|
name = node.name if node.name else call.assigned_variable
|
||||||
if name is not None:
|
if name is not None:
|
||||||
name = self.dedupe(name)
|
name = self.dedupe(name)
|
||||||
|
|
|
@ -27,7 +27,7 @@ class RuleCheckingVisitor(GrammarVisitor):
|
||||||
# TODO: Add line/col info to (leaf) nodes
|
# TODO: Add line/col info to (leaf) nodes
|
||||||
raise GrammarError(f"Dangling reference to rule {node.value!r}")
|
raise GrammarError(f"Dangling reference to rule {node.value!r}")
|
||||||
|
|
||||||
def visit_NamedItem(self, node: NameLeaf) -> None:
|
def visit_NamedItem(self, node: NamedItem) -> None:
|
||||||
if node.name and node.name.startswith("_"):
|
if node.name and node.name.startswith("_"):
|
||||||
raise GrammarError(f"Variable names cannot start with underscore: '{node.name}'")
|
raise GrammarError(f"Variable names cannot start with underscore: '{node.name}'")
|
||||||
self.visit(node.item)
|
self.visit(node.item)
|
||||||
|
@ -57,7 +57,7 @@ class ParserGenerator:
|
||||||
self.all_rules: Dict[str, Rule] = {} # Rules + temporal rules
|
self.all_rules: Dict[str, Rule] = {} # Rules + temporal rules
|
||||||
self._local_variable_stack: List[List[str]] = []
|
self._local_variable_stack: List[List[str]] = []
|
||||||
|
|
||||||
def validate_rule_names(self):
|
def validate_rule_names(self) -> None:
|
||||||
for rule in self.rules:
|
for rule in self.rules:
|
||||||
if rule.startswith("_"):
|
if rule.startswith("_"):
|
||||||
raise GrammarError(f"Rule names cannot start with underscore: '{rule}'")
|
raise GrammarError(f"Rule names cannot start with underscore: '{rule}'")
|
||||||
|
|
Loading…
Reference in New Issue