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