]>
crepu.dev Git - config.git/blob - djavu-asus/elpy/rpc-venv/lib/python3.11/site-packages/parso/pgen2/grammar_parser.py
1 # Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved.
2 # Licensed to PSF under a Contributor Agreement.
5 # Copyright David Halter and Contributors
6 # Modifications are dual-licensed: MIT and PSF.
7 from typing
import Optional
, Iterator
, Tuple
, List
9 from parso
.python
.tokenize
import tokenize
10 from parso
.utils
import parse_version_string
11 from parso
.python
.token
import PythonTokenTypes
15 def __init__(self
, next_
: 'NFAState', nonterminal_or_string
: Optional
[str]):
16 self
.next
: NFAState
= next_
17 self
.nonterminal_or_string
: Optional
[str] = nonterminal_or_string
20 return '<%s: %s>' % (self
.__class
__.__name
__, self
.nonterminal_or_string
)
24 def __init__(self
, from_rule
: str):
25 self
.from_rule
: str = from_rule
26 self
.arcs
: List
[NFAArc
] = []
28 def add_arc(self
, next_
, nonterminal_or_string
=None):
29 assert nonterminal_or_string
is None or isinstance(nonterminal_or_string
, str)
30 assert isinstance(next_
, NFAState
)
31 self
.arcs
.append(NFAArc(next_
, nonterminal_or_string
))
34 return '<%s: from %s>' % (self
.__class
__.__name
__, self
.from_rule
)
39 The parser for Python grammar files.
41 def __init__(self
, bnf_grammar
: str):
42 self
._bnf
_grammar
= bnf_grammar
43 self
.generator
= tokenize(
45 version_info
=parse_version_string('3.9')
47 self
._gettoken
() # Initialize lookahead
49 def parse(self
) -> Iterator
[Tuple
[NFAState
, NFAState
]]:
50 # grammar: (NEWLINE | rule)* ENDMARKER
51 while self
.type != PythonTokenTypes
.ENDMARKER
:
52 while self
.type == PythonTokenTypes
.NEWLINE
:
55 # rule: NAME ':' rhs NEWLINE
56 self
._current
_rule
_name
= self
._expect
(PythonTokenTypes
.NAME
)
57 self
._expect
(PythonTokenTypes
.OP
, ':')
59 a
, z
= self
._parse
_rhs
()
60 self
._expect
(PythonTokenTypes
.NEWLINE
)
65 # rhs: items ('|' items)*
66 a
, z
= self
._parse
_items
()
70 aa
= NFAState(self
._current
_rule
_name
)
71 zz
= NFAState(self
._current
_rule
_name
)
73 # Add the possibility to go into the state of a and come back
81 a
, z
= self
._parse
_items
()
84 def _parse_items(self
):
86 a
, b
= self
._parse
_item
()
87 while self
.type in (PythonTokenTypes
.NAME
, PythonTokenTypes
.STRING
) \
88 or self
.value
in ('(', '['):
89 c
, d
= self
._parse
_item
()
90 # Need to end on the next item.
95 def _parse_item(self
):
96 # item: '[' rhs ']' | atom ['+' | '*']
99 a
, z
= self
._parse
_rhs
()
100 self
._expect
(PythonTokenTypes
.OP
, ']')
101 # Make it also possible that there is no token and change the
106 a
, z
= self
._parse
_atom
()
108 if value
not in ("+", "*"):
111 # Make it clear that we can go back to the old state and repeat.
116 # The end state is the same as the beginning, nothing must
120 def _parse_atom(self
):
121 # atom: '(' rhs ')' | NAME | STRING
122 if self
.value
== "(":
124 a
, z
= self
._parse
_rhs
()
125 self
._expect
(PythonTokenTypes
.OP
, ')')
127 elif self
.type in (PythonTokenTypes
.NAME
, PythonTokenTypes
.STRING
):
128 a
= NFAState(self
._current
_rule
_name
)
129 z
= NFAState(self
._current
_rule
_name
)
130 # Make it clear that the state transition requires that value.
131 a
.add_arc(z
, self
.value
)
135 self
._raise
_error
("expected (...) or NAME or STRING, got %s/%s",
136 self
.type, self
.value
)
138 def _expect(self
, type_
, value
=None):
139 if self
.type != type_
:
140 self
._raise
_error
("expected %s, got %s [%s]",
141 type_
, self
.type, self
.value
)
142 if value
is not None and self
.value
!= value
:
143 self
._raise
_error
("expected %s, got %s", value
, self
.value
)
149 tup
= next(self
.generator
)
150 self
.type, self
.value
, self
.begin
, prefix
= tup
152 def _raise_error(self
, msg
, *args
):
157 msg
= " ".join([msg
] + list(map(str, args
)))
158 line
= self
._bnf
_grammar
.splitlines()[self
.begin
[0] - 1]
159 raise SyntaxError(msg
, ('<grammar>', self
.begin
[0],
160 self
.begin
[1], line
))