Fix typing problems reported by mypy in pegen (GH-20297)

This commit is contained in:
Pablo Galindo 2020-05-21 21:39:44 +01:00 committed by GitHub
parent 2e76820a50
commit d10fef35c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 27 deletions

View File

@ -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)

View File

@ -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}'")