mirror of https://github.com/python/cpython
656 lines
17 KiB
Python
656 lines
17 KiB
Python
#!/usr/bin/env python3.8
|
|
# @generated by pegen from metagrammar.gram
|
|
|
|
import ast
|
|
import sys
|
|
import tokenize
|
|
|
|
from typing import Any, Optional
|
|
|
|
from pegen.parser import memoize, memoize_left_rec, logger, Parser
|
|
from ast import literal_eval
|
|
|
|
from pegen.grammar import (
|
|
Alt,
|
|
Cut,
|
|
Forced,
|
|
Gather,
|
|
Group,
|
|
Item,
|
|
Lookahead,
|
|
LookaheadOrCut,
|
|
MetaTuple,
|
|
MetaList,
|
|
NameLeaf,
|
|
NamedItem,
|
|
NamedItemList,
|
|
NegativeLookahead,
|
|
Opt,
|
|
Plain,
|
|
PositiveLookahead,
|
|
Repeat0,
|
|
Repeat1,
|
|
Rhs,
|
|
Rule,
|
|
RuleList,
|
|
RuleName,
|
|
Grammar,
|
|
StringLeaf,
|
|
)
|
|
|
|
# Keywords and soft keywords are listed at the end of the parser definition.
|
|
class GeneratedParser(Parser):
|
|
|
|
@memoize
|
|
def start(self) -> Optional[Grammar]:
|
|
# start: grammar $
|
|
mark = self._mark()
|
|
if (
|
|
(grammar := self.grammar())
|
|
and
|
|
(_endmarker := self.expect('ENDMARKER'))
|
|
):
|
|
return grammar
|
|
self._reset(mark)
|
|
return None
|
|
|
|
@memoize
|
|
def grammar(self) -> Optional[Grammar]:
|
|
# grammar: metas rules | rules
|
|
mark = self._mark()
|
|
if (
|
|
(metas := self.metas())
|
|
and
|
|
(rules := self.rules())
|
|
):
|
|
return Grammar ( rules , metas )
|
|
self._reset(mark)
|
|
if (
|
|
(rules := self.rules())
|
|
):
|
|
return Grammar ( rules , [] )
|
|
self._reset(mark)
|
|
return None
|
|
|
|
@memoize
|
|
def metas(self) -> Optional[MetaList]:
|
|
# metas: meta metas | meta
|
|
mark = self._mark()
|
|
if (
|
|
(meta := self.meta())
|
|
and
|
|
(metas := self.metas())
|
|
):
|
|
return [meta] + metas
|
|
self._reset(mark)
|
|
if (
|
|
(meta := self.meta())
|
|
):
|
|
return [meta]
|
|
self._reset(mark)
|
|
return None
|
|
|
|
@memoize
|
|
def meta(self) -> Optional[MetaTuple]:
|
|
# meta: "@" NAME NEWLINE | "@" NAME NAME NEWLINE | "@" NAME STRING NEWLINE
|
|
mark = self._mark()
|
|
if (
|
|
(literal := self.expect("@"))
|
|
and
|
|
(name := self.name())
|
|
and
|
|
(_newline := self.expect('NEWLINE'))
|
|
):
|
|
return ( name . string , None )
|
|
self._reset(mark)
|
|
if (
|
|
(literal := self.expect("@"))
|
|
and
|
|
(a := self.name())
|
|
and
|
|
(b := self.name())
|
|
and
|
|
(_newline := self.expect('NEWLINE'))
|
|
):
|
|
return ( a . string , b . string )
|
|
self._reset(mark)
|
|
if (
|
|
(literal := self.expect("@"))
|
|
and
|
|
(name := self.name())
|
|
and
|
|
(string := self.string())
|
|
and
|
|
(_newline := self.expect('NEWLINE'))
|
|
):
|
|
return ( name . string , literal_eval ( string . string ) )
|
|
self._reset(mark)
|
|
return None
|
|
|
|
@memoize
|
|
def rules(self) -> Optional[RuleList]:
|
|
# rules: rule rules | rule
|
|
mark = self._mark()
|
|
if (
|
|
(rule := self.rule())
|
|
and
|
|
(rules := self.rules())
|
|
):
|
|
return [rule] + rules
|
|
self._reset(mark)
|
|
if (
|
|
(rule := self.rule())
|
|
):
|
|
return [rule]
|
|
self._reset(mark)
|
|
return None
|
|
|
|
@memoize
|
|
def rule(self) -> Optional[Rule]:
|
|
# rule: rulename memoflag? ":" alts NEWLINE INDENT more_alts DEDENT | rulename memoflag? ":" NEWLINE INDENT more_alts DEDENT | rulename memoflag? ":" alts NEWLINE
|
|
mark = self._mark()
|
|
if (
|
|
(rulename := self.rulename())
|
|
and
|
|
(opt := self.memoflag(),)
|
|
and
|
|
(literal := self.expect(":"))
|
|
and
|
|
(alts := self.alts())
|
|
and
|
|
(_newline := self.expect('NEWLINE'))
|
|
and
|
|
(_indent := self.expect('INDENT'))
|
|
and
|
|
(more_alts := self.more_alts())
|
|
and
|
|
(_dedent := self.expect('DEDENT'))
|
|
):
|
|
return Rule ( rulename [0] , rulename [1] , Rhs ( alts . alts + more_alts . alts ) , memo = opt )
|
|
self._reset(mark)
|
|
if (
|
|
(rulename := self.rulename())
|
|
and
|
|
(opt := self.memoflag(),)
|
|
and
|
|
(literal := self.expect(":"))
|
|
and
|
|
(_newline := self.expect('NEWLINE'))
|
|
and
|
|
(_indent := self.expect('INDENT'))
|
|
and
|
|
(more_alts := self.more_alts())
|
|
and
|
|
(_dedent := self.expect('DEDENT'))
|
|
):
|
|
return Rule ( rulename [0] , rulename [1] , more_alts , memo = opt )
|
|
self._reset(mark)
|
|
if (
|
|
(rulename := self.rulename())
|
|
and
|
|
(opt := self.memoflag(),)
|
|
and
|
|
(literal := self.expect(":"))
|
|
and
|
|
(alts := self.alts())
|
|
and
|
|
(_newline := self.expect('NEWLINE'))
|
|
):
|
|
return Rule ( rulename [0] , rulename [1] , alts , memo = opt )
|
|
self._reset(mark)
|
|
return None
|
|
|
|
@memoize
|
|
def rulename(self) -> Optional[RuleName]:
|
|
# rulename: NAME annotation | NAME
|
|
mark = self._mark()
|
|
if (
|
|
(name := self.name())
|
|
and
|
|
(annotation := self.annotation())
|
|
):
|
|
return ( name . string , annotation )
|
|
self._reset(mark)
|
|
if (
|
|
(name := self.name())
|
|
):
|
|
return ( name . string , None )
|
|
self._reset(mark)
|
|
return None
|
|
|
|
@memoize
|
|
def memoflag(self) -> Optional[str]:
|
|
# memoflag: '(' "memo" ')'
|
|
mark = self._mark()
|
|
if (
|
|
(literal := self.expect('('))
|
|
and
|
|
(literal_1 := self.expect("memo"))
|
|
and
|
|
(literal_2 := self.expect(')'))
|
|
):
|
|
return "memo"
|
|
self._reset(mark)
|
|
return None
|
|
|
|
@memoize
|
|
def alts(self) -> Optional[Rhs]:
|
|
# alts: alt "|" alts | alt
|
|
mark = self._mark()
|
|
if (
|
|
(alt := self.alt())
|
|
and
|
|
(literal := self.expect("|"))
|
|
and
|
|
(alts := self.alts())
|
|
):
|
|
return Rhs ( [alt] + alts . alts )
|
|
self._reset(mark)
|
|
if (
|
|
(alt := self.alt())
|
|
):
|
|
return Rhs ( [alt] )
|
|
self._reset(mark)
|
|
return None
|
|
|
|
@memoize
|
|
def more_alts(self) -> Optional[Rhs]:
|
|
# more_alts: "|" alts NEWLINE more_alts | "|" alts NEWLINE
|
|
mark = self._mark()
|
|
if (
|
|
(literal := self.expect("|"))
|
|
and
|
|
(alts := self.alts())
|
|
and
|
|
(_newline := self.expect('NEWLINE'))
|
|
and
|
|
(more_alts := self.more_alts())
|
|
):
|
|
return Rhs ( alts . alts + more_alts . alts )
|
|
self._reset(mark)
|
|
if (
|
|
(literal := self.expect("|"))
|
|
and
|
|
(alts := self.alts())
|
|
and
|
|
(_newline := self.expect('NEWLINE'))
|
|
):
|
|
return Rhs ( alts . alts )
|
|
self._reset(mark)
|
|
return None
|
|
|
|
@memoize
|
|
def alt(self) -> Optional[Alt]:
|
|
# alt: items '$' action | items '$' | items action | items
|
|
mark = self._mark()
|
|
if (
|
|
(items := self.items())
|
|
and
|
|
(literal := self.expect('$'))
|
|
and
|
|
(action := self.action())
|
|
):
|
|
return Alt ( items + [NamedItem ( None , NameLeaf ( 'ENDMARKER' ) )] , action = action )
|
|
self._reset(mark)
|
|
if (
|
|
(items := self.items())
|
|
and
|
|
(literal := self.expect('$'))
|
|
):
|
|
return Alt ( items + [NamedItem ( None , NameLeaf ( 'ENDMARKER' ) )] , action = None )
|
|
self._reset(mark)
|
|
if (
|
|
(items := self.items())
|
|
and
|
|
(action := self.action())
|
|
):
|
|
return Alt ( items , action = action )
|
|
self._reset(mark)
|
|
if (
|
|
(items := self.items())
|
|
):
|
|
return Alt ( items , action = None )
|
|
self._reset(mark)
|
|
return None
|
|
|
|
@memoize
|
|
def items(self) -> Optional[NamedItemList]:
|
|
# items: named_item items | named_item
|
|
mark = self._mark()
|
|
if (
|
|
(named_item := self.named_item())
|
|
and
|
|
(items := self.items())
|
|
):
|
|
return [named_item] + items
|
|
self._reset(mark)
|
|
if (
|
|
(named_item := self.named_item())
|
|
):
|
|
return [named_item]
|
|
self._reset(mark)
|
|
return None
|
|
|
|
@memoize
|
|
def named_item(self) -> Optional[NamedItem]:
|
|
# named_item: NAME annotation '=' ~ item | NAME '=' ~ item | item | forced_atom | lookahead
|
|
mark = self._mark()
|
|
cut = False
|
|
if (
|
|
(name := self.name())
|
|
and
|
|
(annotation := self.annotation())
|
|
and
|
|
(literal := self.expect('='))
|
|
and
|
|
(cut := True)
|
|
and
|
|
(item := self.item())
|
|
):
|
|
return NamedItem ( name . string , item , annotation )
|
|
self._reset(mark)
|
|
if cut: return None
|
|
cut = False
|
|
if (
|
|
(name := self.name())
|
|
and
|
|
(literal := self.expect('='))
|
|
and
|
|
(cut := True)
|
|
and
|
|
(item := self.item())
|
|
):
|
|
return NamedItem ( name . string , item )
|
|
self._reset(mark)
|
|
if cut: return None
|
|
if (
|
|
(item := self.item())
|
|
):
|
|
return NamedItem ( None , item )
|
|
self._reset(mark)
|
|
if (
|
|
(forced := self.forced_atom())
|
|
):
|
|
return NamedItem ( None , forced )
|
|
self._reset(mark)
|
|
if (
|
|
(it := self.lookahead())
|
|
):
|
|
return NamedItem ( None , it )
|
|
self._reset(mark)
|
|
return None
|
|
|
|
@memoize
|
|
def forced_atom(self) -> Optional[Forced]:
|
|
# forced_atom: '&' '&' ~ atom
|
|
mark = self._mark()
|
|
cut = False
|
|
if (
|
|
(literal := self.expect('&'))
|
|
and
|
|
(literal_1 := self.expect('&'))
|
|
and
|
|
(cut := True)
|
|
and
|
|
(atom := self.atom())
|
|
):
|
|
return Forced ( atom )
|
|
self._reset(mark)
|
|
if cut: return None
|
|
return None
|
|
|
|
@memoize
|
|
def lookahead(self) -> Optional[LookaheadOrCut]:
|
|
# lookahead: '&' ~ atom | '!' ~ atom | '~'
|
|
mark = self._mark()
|
|
cut = False
|
|
if (
|
|
(literal := self.expect('&'))
|
|
and
|
|
(cut := True)
|
|
and
|
|
(atom := self.atom())
|
|
):
|
|
return PositiveLookahead ( atom )
|
|
self._reset(mark)
|
|
if cut: return None
|
|
cut = False
|
|
if (
|
|
(literal := self.expect('!'))
|
|
and
|
|
(cut := True)
|
|
and
|
|
(atom := self.atom())
|
|
):
|
|
return NegativeLookahead ( atom )
|
|
self._reset(mark)
|
|
if cut: return None
|
|
if (
|
|
(literal := self.expect('~'))
|
|
):
|
|
return Cut ( )
|
|
self._reset(mark)
|
|
return None
|
|
|
|
@memoize
|
|
def item(self) -> Optional[Item]:
|
|
# item: '[' ~ alts ']' | atom '?' | atom '*' | atom '+' | atom '.' atom '+' | atom
|
|
mark = self._mark()
|
|
cut = False
|
|
if (
|
|
(literal := self.expect('['))
|
|
and
|
|
(cut := True)
|
|
and
|
|
(alts := self.alts())
|
|
and
|
|
(literal_1 := self.expect(']'))
|
|
):
|
|
return Opt ( alts )
|
|
self._reset(mark)
|
|
if cut: return None
|
|
if (
|
|
(atom := self.atom())
|
|
and
|
|
(literal := self.expect('?'))
|
|
):
|
|
return Opt ( atom )
|
|
self._reset(mark)
|
|
if (
|
|
(atom := self.atom())
|
|
and
|
|
(literal := self.expect('*'))
|
|
):
|
|
return Repeat0 ( atom )
|
|
self._reset(mark)
|
|
if (
|
|
(atom := self.atom())
|
|
and
|
|
(literal := self.expect('+'))
|
|
):
|
|
return Repeat1 ( atom )
|
|
self._reset(mark)
|
|
if (
|
|
(sep := self.atom())
|
|
and
|
|
(literal := self.expect('.'))
|
|
and
|
|
(node := self.atom())
|
|
and
|
|
(literal_1 := self.expect('+'))
|
|
):
|
|
return Gather ( sep , node )
|
|
self._reset(mark)
|
|
if (
|
|
(atom := self.atom())
|
|
):
|
|
return atom
|
|
self._reset(mark)
|
|
return None
|
|
|
|
@memoize
|
|
def atom(self) -> Optional[Plain]:
|
|
# atom: '(' ~ alts ')' | NAME | STRING
|
|
mark = self._mark()
|
|
cut = False
|
|
if (
|
|
(literal := self.expect('('))
|
|
and
|
|
(cut := True)
|
|
and
|
|
(alts := self.alts())
|
|
and
|
|
(literal_1 := self.expect(')'))
|
|
):
|
|
return Group ( alts )
|
|
self._reset(mark)
|
|
if cut: return None
|
|
if (
|
|
(name := self.name())
|
|
):
|
|
return NameLeaf ( name . string )
|
|
self._reset(mark)
|
|
if (
|
|
(string := self.string())
|
|
):
|
|
return StringLeaf ( string . string )
|
|
self._reset(mark)
|
|
return None
|
|
|
|
@memoize
|
|
def action(self) -> Optional[str]:
|
|
# action: "{" ~ target_atoms "}"
|
|
mark = self._mark()
|
|
cut = False
|
|
if (
|
|
(literal := self.expect("{"))
|
|
and
|
|
(cut := True)
|
|
and
|
|
(target_atoms := self.target_atoms())
|
|
and
|
|
(literal_1 := self.expect("}"))
|
|
):
|
|
return target_atoms
|
|
self._reset(mark)
|
|
if cut: return None
|
|
return None
|
|
|
|
@memoize
|
|
def annotation(self) -> Optional[str]:
|
|
# annotation: "[" ~ target_atoms "]"
|
|
mark = self._mark()
|
|
cut = False
|
|
if (
|
|
(literal := self.expect("["))
|
|
and
|
|
(cut := True)
|
|
and
|
|
(target_atoms := self.target_atoms())
|
|
and
|
|
(literal_1 := self.expect("]"))
|
|
):
|
|
return target_atoms
|
|
self._reset(mark)
|
|
if cut: return None
|
|
return None
|
|
|
|
@memoize
|
|
def target_atoms(self) -> Optional[str]:
|
|
# target_atoms: target_atom target_atoms | target_atom
|
|
mark = self._mark()
|
|
if (
|
|
(target_atom := self.target_atom())
|
|
and
|
|
(target_atoms := self.target_atoms())
|
|
):
|
|
return target_atom + " " + target_atoms
|
|
self._reset(mark)
|
|
if (
|
|
(target_atom := self.target_atom())
|
|
):
|
|
return target_atom
|
|
self._reset(mark)
|
|
return None
|
|
|
|
@memoize
|
|
def target_atom(self) -> Optional[str]:
|
|
# target_atom: "{" ~ target_atoms? "}" | "[" ~ target_atoms? "]" | NAME "*" | NAME | NUMBER | STRING | "?" | ":" | !"}" !"]" OP
|
|
mark = self._mark()
|
|
cut = False
|
|
if (
|
|
(literal := self.expect("{"))
|
|
and
|
|
(cut := True)
|
|
and
|
|
(atoms := self.target_atoms(),)
|
|
and
|
|
(literal_1 := self.expect("}"))
|
|
):
|
|
return "{" + ( atoms or "" ) + "}"
|
|
self._reset(mark)
|
|
if cut: return None
|
|
cut = False
|
|
if (
|
|
(literal := self.expect("["))
|
|
and
|
|
(cut := True)
|
|
and
|
|
(atoms := self.target_atoms(),)
|
|
and
|
|
(literal_1 := self.expect("]"))
|
|
):
|
|
return "[" + ( atoms or "" ) + "]"
|
|
self._reset(mark)
|
|
if cut: return None
|
|
if (
|
|
(name := self.name())
|
|
and
|
|
(literal := self.expect("*"))
|
|
):
|
|
return name . string + "*"
|
|
self._reset(mark)
|
|
if (
|
|
(name := self.name())
|
|
):
|
|
return name . string
|
|
self._reset(mark)
|
|
if (
|
|
(number := self.number())
|
|
):
|
|
return number . string
|
|
self._reset(mark)
|
|
if (
|
|
(string := self.string())
|
|
):
|
|
return string . string
|
|
self._reset(mark)
|
|
if (
|
|
(literal := self.expect("?"))
|
|
):
|
|
return "?"
|
|
self._reset(mark)
|
|
if (
|
|
(literal := self.expect(":"))
|
|
):
|
|
return ":"
|
|
self._reset(mark)
|
|
if (
|
|
self.negative_lookahead(self.expect, "}")
|
|
and
|
|
self.negative_lookahead(self.expect, "]")
|
|
and
|
|
(op := self.op())
|
|
):
|
|
return op . string
|
|
self._reset(mark)
|
|
return None
|
|
|
|
KEYWORDS = ()
|
|
SOFT_KEYWORDS = ('memo',)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
from pegen.parser import simple_parser_main
|
|
simple_parser_main(GeneratedParser)
|