MCPcopy Index your code
hub / github.com/python/cpython / PythonParserGenerator

Class PythonParserGenerator

Tools/peg_generator/pegen/python_generator.py:215–368  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

213
214
215class PythonParserGenerator(ParserGenerator, GrammarVisitor):
216 def __init__(
217 self,
218 grammar: grammar.Grammar,
219 file: IO[str] | None,
220 tokens: set[str] = set(token.tok_name.values()),
221 location_formatting: str | None = None,
222 unreachable_formatting: str | None = None,
223 ):
224 tokens.add("SOFT_KEYWORD")
225 super().__init__(grammar, tokens, file)
226 self.callmakervisitor: PythonCallMakerVisitor = PythonCallMakerVisitor(self)
227 self.invalidvisitor: InvalidNodeVisitor = InvalidNodeVisitor()
228 self.unreachable_formatting = unreachable_formatting or "None # pragma: no cover"
229 self.location_formatting = (
230 location_formatting
231 or "lineno=start_lineno, col_offset=start_col_offset, "
232 "end_lineno=end_lineno, end_col_offset=end_col_offset"
233 )
234
235 def generate(self, filename: str) -> None:
236 self.collect_rules()
237 header = self.grammar.metas.get("header", MODULE_PREFIX)
238 if header is not None:
239 basename = os.path.basename(filename)
240 self.print(header.rstrip("\n").format(filename=basename))
241 subheader = self.grammar.metas.get("subheader", "")
242 if subheader:
243 self.print(subheader)
244 cls_name = self.grammar.metas.get("class", "GeneratedParser")
245 self.print("# Keywords and soft keywords are listed at the end of the parser definition.")
246 self.print(f"class {cls_name}(Parser):")
247 for rule in self.all_rules.values():
248 self.print()
249 with self.indent():
250 self.visit(rule)
251
252 self.print()
253 with self.indent():
254 self.print(f"KEYWORDS = {tuple(self.keywords)}")
255 self.print(f"SOFT_KEYWORDS = {tuple(self.soft_keywords)}")
256
257 trailer = self.grammar.metas.get("trailer", MODULE_SUFFIX.format(class_name=cls_name))
258 if trailer is not None:
259 self.print(trailer.rstrip("\n"))
260
261 def alts_uses_locations(self, alts: Sequence[Alt]) -> bool:
262 for alt in alts:
263 if alt.action and "LOCATIONS" in alt.action:
264 return True
265 for n in alt.items:
266 if isinstance(n.item, Group) and self.alts_uses_locations(n.item.rhs.alts):
267 return True
268 return False
269
270 def visit_Rule(self, node: Rule) -> None:
271 is_loop = node.is_loop()
272 is_gather = node.is_gather()

Calls

no outgoing calls

Used in the wild real call sites across dependent graphs

searching dependent graphs…