(root)/
Python-3.11.7/
Tools/
peg_generator/
pegen/
grammar.py
       1  from __future__ import annotations
       2  
       3  from abc import abstractmethod
       4  from typing import (
       5      TYPE_CHECKING,
       6      AbstractSet,
       7      Any,
       8      Dict,
       9      Iterable,
      10      Iterator,
      11      List,
      12      Optional,
      13      Set,
      14      Tuple,
      15      Union,
      16  )
      17  
      18  if TYPE_CHECKING:
      19      from pegen.parser_generator import ParserGenerator
      20  
      21  
      22  class ESC[4;38;5;81mGrammarError(ESC[4;38;5;149mException):
      23      pass
      24  
      25  
      26  class ESC[4;38;5;81mGrammarVisitor:
      27      def visit(self, node: Any, *args: Any, **kwargs: Any) -> Any:
      28          """Visit a node."""
      29          method = "visit_" + node.__class__.__name__
      30          visitor = getattr(self, method, self.generic_visit)
      31          return visitor(node, *args, **kwargs)
      32  
      33      def generic_visit(self, node: Iterable[Any], *args: Any, **kwargs: Any) -> Any:
      34          """Called if no explicit visitor function exists for a node."""
      35          for value in node:
      36              if isinstance(value, list):
      37                  for item in value:
      38                      self.visit(item, *args, **kwargs)
      39              else:
      40                  self.visit(value, *args, **kwargs)
      41  
      42  
      43  class ESC[4;38;5;81mGrammar:
      44      def __init__(self, rules: Iterable[Rule], metas: Iterable[Tuple[str, Optional[str]]]):
      45          self.rules = {rule.name: rule for rule in rules}
      46          self.metas = dict(metas)
      47  
      48      def __str__(self) -> str:
      49          return "\n".join(str(rule) for name, rule in self.rules.items())
      50  
      51      def __repr__(self) -> str:
      52          lines = ["Grammar("]
      53          lines.append("  [")
      54          for rule in self.rules.values():
      55              lines.append(f"    {repr(rule)},")
      56          lines.append("  ],")
      57          lines.append("  {repr(list(self.metas.items()))}")
      58          lines.append(")")
      59          return "\n".join(lines)
      60  
      61      def __iter__(self) -> Iterator[Rule]:
      62          yield from self.rules.values()
      63  
      64  
      65  # Global flag whether we want actions in __str__() -- default off.
      66  SIMPLE_STR = True
      67  
      68  
      69  class ESC[4;38;5;81mRule:
      70      def __init__(self, name: str, type: Optional[str], rhs: Rhs, memo: Optional[object] = None):
      71          self.name = name
      72          self.type = type
      73          self.rhs = rhs
      74          self.memo = bool(memo)
      75          self.left_recursive = False
      76          self.leader = False
      77  
      78      def is_loop(self) -> bool:
      79          return self.name.startswith("_loop")
      80  
      81      def is_gather(self) -> bool:
      82          return self.name.startswith("_gather")
      83  
      84      def __str__(self) -> str:
      85          if SIMPLE_STR or self.type is None:
      86              res = f"{self.name}: {self.rhs}"
      87          else:
      88              res = f"{self.name}[{self.type}]: {self.rhs}"
      89          if len(res) < 88:
      90              return res
      91          lines = [res.split(":")[0] + ":"]
      92          lines += [f"    | {alt}" for alt in self.rhs.alts]
      93          return "\n".join(lines)
      94  
      95      def __repr__(self) -> str:
      96          return f"Rule({self.name!r}, {self.type!r}, {self.rhs!r})"
      97  
      98      def __iter__(self) -> Iterator[Rhs]:
      99          yield self.rhs
     100  
     101      def flatten(self) -> Rhs:
     102          # If it's a single parenthesized group, flatten it.
     103          rhs = self.rhs
     104          if (
     105              not self.is_loop()
     106              and len(rhs.alts) == 1
     107              and len(rhs.alts[0].items) == 1
     108              and isinstance(rhs.alts[0].items[0].item, Group)
     109          ):
     110              rhs = rhs.alts[0].items[0].item.rhs
     111          return rhs
     112  
     113  
     114  class ESC[4;38;5;81mLeaf:
     115      def __init__(self, value: str):
     116          self.value = value
     117  
     118      def __str__(self) -> str:
     119          return self.value
     120  
     121      def __iter__(self) -> Iterable[str]:
     122          if False:
     123              yield
     124  
     125  
     126  class ESC[4;38;5;81mNameLeaf(ESC[4;38;5;149mLeaf):
     127      """The value is the name."""
     128  
     129      def __str__(self) -> str:
     130          if self.value == "ENDMARKER":
     131              return "$"
     132          return super().__str__()
     133  
     134      def __repr__(self) -> str:
     135          return f"NameLeaf({self.value!r})"
     136  
     137  
     138  class ESC[4;38;5;81mStringLeaf(ESC[4;38;5;149mLeaf):
     139      """The value is a string literal, including quotes."""
     140  
     141      def __repr__(self) -> str:
     142          return f"StringLeaf({self.value!r})"
     143  
     144  
     145  class ESC[4;38;5;81mRhs:
     146      def __init__(self, alts: List[Alt]):
     147          self.alts = alts
     148          self.memo: Optional[Tuple[Optional[str], str]] = None
     149  
     150      def __str__(self) -> str:
     151          return " | ".join(str(alt) for alt in self.alts)
     152  
     153      def __repr__(self) -> str:
     154          return f"Rhs({self.alts!r})"
     155  
     156      def __iter__(self) -> Iterator[List[Alt]]:
     157          yield self.alts
     158  
     159      @property
     160      def can_be_inlined(self) -> bool:
     161          if len(self.alts) != 1 or len(self.alts[0].items) != 1:
     162              return False
     163          # If the alternative has an action we cannot inline
     164          if getattr(self.alts[0], "action", None) is not None:
     165              return False
     166          return True
     167  
     168  
     169  class ESC[4;38;5;81mAlt:
     170      def __init__(self, items: List[NamedItem], *, icut: int = -1, action: Optional[str] = None):
     171          self.items = items
     172          self.icut = icut
     173          self.action = action
     174  
     175      def __str__(self) -> str:
     176          core = " ".join(str(item) for item in self.items)
     177          if not SIMPLE_STR and self.action:
     178              return f"{core} {{ {self.action} }}"
     179          else:
     180              return core
     181  
     182      def __repr__(self) -> str:
     183          args = [repr(self.items)]
     184          if self.icut >= 0:
     185              args.append(f"icut={self.icut}")
     186          if self.action:
     187              args.append(f"action={self.action!r}")
     188          return f"Alt({', '.join(args)})"
     189  
     190      def __iter__(self) -> Iterator[List[NamedItem]]:
     191          yield self.items
     192  
     193  
     194  class ESC[4;38;5;81mNamedItem:
     195      def __init__(self, name: Optional[str], item: Item, type: Optional[str] = None):
     196          self.name = name
     197          self.item = item
     198          self.type = type
     199  
     200      def __str__(self) -> str:
     201          if not SIMPLE_STR and self.name:
     202              return f"{self.name}={self.item}"
     203          else:
     204              return str(self.item)
     205  
     206      def __repr__(self) -> str:
     207          return f"NamedItem({self.name!r}, {self.item!r})"
     208  
     209      def __iter__(self) -> Iterator[Item]:
     210          yield self.item
     211  
     212  
     213  class ESC[4;38;5;81mForced:
     214      def __init__(self, node: Plain):
     215          self.node = node
     216  
     217      def __str__(self) -> str:
     218          return f"&&{self.node}"
     219  
     220      def __iter__(self) -> Iterator[Plain]:
     221          yield self.node
     222  
     223  
     224  class ESC[4;38;5;81mLookahead:
     225      def __init__(self, node: Plain, sign: str):
     226          self.node = node
     227          self.sign = sign
     228  
     229      def __str__(self) -> str:
     230          return f"{self.sign}{self.node}"
     231  
     232      def __iter__(self) -> Iterator[Plain]:
     233          yield self.node
     234  
     235  
     236  class ESC[4;38;5;81mPositiveLookahead(ESC[4;38;5;149mLookahead):
     237      def __init__(self, node: Plain):
     238          super().__init__(node, "&")
     239  
     240      def __repr__(self) -> str:
     241          return f"PositiveLookahead({self.node!r})"
     242  
     243  
     244  class ESC[4;38;5;81mNegativeLookahead(ESC[4;38;5;149mLookahead):
     245      def __init__(self, node: Plain):
     246          super().__init__(node, "!")
     247  
     248      def __repr__(self) -> str:
     249          return f"NegativeLookahead({self.node!r})"
     250  
     251  
     252  class ESC[4;38;5;81mOpt:
     253      def __init__(self, node: Item):
     254          self.node = node
     255  
     256      def __str__(self) -> str:
     257          s = str(self.node)
     258          # TODO: Decide whether to use [X] or X? based on type of X
     259          if " " in s:
     260              return f"[{s}]"
     261          else:
     262              return f"{s}?"
     263  
     264      def __repr__(self) -> str:
     265          return f"Opt({self.node!r})"
     266  
     267      def __iter__(self) -> Iterator[Item]:
     268          yield self.node
     269  
     270  
     271  class ESC[4;38;5;81mRepeat:
     272      """Shared base class for x* and x+."""
     273  
     274      def __init__(self, node: Plain):
     275          self.node = node
     276          self.memo: Optional[Tuple[Optional[str], str]] = None
     277  
     278      def __iter__(self) -> Iterator[Plain]:
     279          yield self.node
     280  
     281  
     282  class ESC[4;38;5;81mRepeat0(ESC[4;38;5;149mRepeat):
     283      def __str__(self) -> str:
     284          s = str(self.node)
     285          # TODO: Decide whether to use (X)* or X* based on type of X
     286          if " " in s:
     287              return f"({s})*"
     288          else:
     289              return f"{s}*"
     290  
     291      def __repr__(self) -> str:
     292          return f"Repeat0({self.node!r})"
     293  
     294  
     295  class ESC[4;38;5;81mRepeat1(ESC[4;38;5;149mRepeat):
     296      def __str__(self) -> str:
     297          s = str(self.node)
     298          # TODO: Decide whether to use (X)+ or X+ based on type of X
     299          if " " in s:
     300              return f"({s})+"
     301          else:
     302              return f"{s}+"
     303  
     304      def __repr__(self) -> str:
     305          return f"Repeat1({self.node!r})"
     306  
     307  
     308  class ESC[4;38;5;81mGather(ESC[4;38;5;149mRepeat):
     309      def __init__(self, separator: Plain, node: Plain):
     310          self.separator = separator
     311          self.node = node
     312  
     313      def __str__(self) -> str:
     314          return f"{self.separator!s}.{self.node!s}+"
     315  
     316      def __repr__(self) -> str:
     317          return f"Gather({self.separator!r}, {self.node!r})"
     318  
     319  
     320  class ESC[4;38;5;81mGroup:
     321      def __init__(self, rhs: Rhs):
     322          self.rhs = rhs
     323  
     324      def __str__(self) -> str:
     325          return f"({self.rhs})"
     326  
     327      def __repr__(self) -> str:
     328          return f"Group({self.rhs!r})"
     329  
     330      def __iter__(self) -> Iterator[Rhs]:
     331          yield self.rhs
     332  
     333  
     334  class ESC[4;38;5;81mCut:
     335      def __init__(self) -> None:
     336          pass
     337  
     338      def __repr__(self) -> str:
     339          return f"Cut()"
     340  
     341      def __str__(self) -> str:
     342          return f"~"
     343  
     344      def __iter__(self) -> Iterator[Tuple[str, str]]:
     345          if False:
     346              yield
     347  
     348      def __eq__(self, other: object) -> bool:
     349          if not isinstance(other, Cut):
     350              return NotImplemented
     351          return True
     352  
     353      def initial_names(self) -> AbstractSet[str]:
     354          return set()
     355  
     356  
     357  Plain = Union[Leaf, Group]
     358  Item = Union[Plain, Opt, Repeat, Forced, Lookahead, Rhs, Cut]
     359  RuleName = Tuple[str, str]
     360  MetaTuple = Tuple[str, Optional[str]]
     361  MetaList = List[MetaTuple]
     362  RuleList = List[Rule]
     363  NamedItemList = List[NamedItem]
     364  LookaheadOrCut = Union[Lookahead, Cut]