1
+ import os
2
+ import sys
1
3
import collections
2
- from lib2to3 . pgen2 import tokenize
4
+ import importlib . machinery
3
5
4
- from . import token , grammar
6
+ # Use Lib/token.py and Lib/tokenize.py to obtain the tokens. To maintain this
7
+ # compatible with older versions of Python, we need to make sure that we only
8
+ # import these two files (and not any of the dependencies of these files).
9
+
10
+ CURRENT_FOLDER_LOCATION = os .path .dirname (os .path .realpath (__file__ ))
11
+ LIB_LOCATION = os .path .realpath (os .path .join (CURRENT_FOLDER_LOCATION , '..' , '..' , 'Lib' ))
12
+ TOKEN_LOCATION = os .path .join (LIB_LOCATION , 'token.py' )
13
+ TOKENIZE_LOCATION = os .path .join (LIB_LOCATION , 'tokenize.py' )
14
+
15
+ token = importlib .machinery .SourceFileLoader ('token' ,
16
+ TOKEN_LOCATION ).load_module ()
17
+ # Add token to the module cache so tokenize.py uses that excact one instead of
18
+ # the one in the stdlib of the interpreter executing this file.
19
+ sys .modules ['token' ] = token
20
+ tokenize = importlib .machinery .SourceFileLoader ('tokenize' ,
21
+ TOKENIZE_LOCATION ).load_module ()
22
+
23
+ from . import grammar
5
24
6
25
class ParserGenerator (object ):
7
26
8
- def __init__ (self , filename , tokens , stream = None , verbose = False ):
27
+ def __init__ (self , filename , stream = None , verbose = False ):
9
28
close_stream = None
10
29
if stream is None :
11
30
stream = open (filename )
12
31
close_stream = stream .close
13
- self .tokens = dict (token .generate_tokens (tokens ))
14
- self .opmap = dict (token .generate_opmap (tokens ))
32
+ self .tokens = token
33
+ self .opmap = token .EXACT_TOKEN_TYPES
34
+ # Manually add <> so it does not collide with !=
35
+ self .opmap ['<>' ] = self .tokens .NOTEQUAL
15
36
self .verbose = verbose
16
37
self .filename = filename
17
38
self .stream = stream
@@ -87,9 +108,9 @@ def make_label(self, c, label):
87
108
return ilabel
88
109
else :
89
110
# A named token (NAME, NUMBER, STRING)
90
- itoken = self .tokens . get ( label , None )
111
+ itoken = getattr ( self .tokens , label , None )
91
112
assert isinstance (itoken , int ), label
92
- assert itoken in self .tokens .values () , label
113
+ assert itoken in self .tokens .tok_name , label
93
114
if itoken in c .tokens :
94
115
return c .tokens [itoken ]
95
116
else :
@@ -105,12 +126,12 @@ def make_label(self, c, label):
105
126
if value in c .keywords :
106
127
return c .keywords [value ]
107
128
else :
108
- c .labels .append ((self .tokens [ ' NAME' ] , value ))
129
+ c .labels .append ((self .tokens . NAME , value ))
109
130
c .keywords [value ] = ilabel
110
131
return ilabel
111
132
else :
112
133
# An operator (any non-numeric token)
113
- itoken = self .tokens [ self . opmap [value ] ] # Fails if unknown token
134
+ itoken = self .opmap [value ] # Fails if unknown token
114
135
if itoken in c .tokens :
115
136
return c .tokens [itoken ]
116
137
else :
@@ -163,16 +184,16 @@ def parse(self):
163
184
dfas = collections .OrderedDict ()
164
185
startsymbol = None
165
186
# MSTART: (NEWLINE | RULE)* ENDMARKER
166
- while self .type != self .tokens [ ' ENDMARKER' ] :
167
- while self .type == self .tokens [ ' NEWLINE' ] :
187
+ while self .type != self .tokens . ENDMARKER :
188
+ while self .type == self .tokens . NEWLINE :
168
189
self .gettoken ()
169
190
# RULE: NAME ':' RHS NEWLINE
170
- name = self .expect (self .tokens [ ' NAME' ] )
191
+ name = self .expect (self .tokens . NAME )
171
192
if self .verbose :
172
193
print ("Processing rule {dfa_name}" .format (dfa_name = name ))
173
- self .expect (self .tokens [ 'OP' ] , ":" )
194
+ self .expect (self .tokens . OP , ":" )
174
195
a , z = self .parse_rhs ()
175
- self .expect (self .tokens [ ' NEWLINE' ] )
196
+ self .expect (self .tokens . NEWLINE )
176
197
if self .verbose :
177
198
self .dump_nfa (name , a , z )
178
199
dfa = self .make_dfa (a , z )
@@ -288,7 +309,7 @@ def parse_alt(self):
288
309
# ALT: ITEM+
289
310
a , b = self .parse_item ()
290
311
while (self .value in ("(" , "[" ) or
291
- self .type in (self .tokens [ ' NAME' ] , self .tokens [ ' STRING' ] )):
312
+ self .type in (self .tokens . NAME , self .tokens . STRING )):
292
313
c , d = self .parse_item ()
293
314
b .addarc (c )
294
315
b = d
@@ -299,7 +320,7 @@ def parse_item(self):
299
320
if self .value == "[" :
300
321
self .gettoken ()
301
322
a , z = self .parse_rhs ()
302
- self .expect (self .tokens [ 'OP' ] , "]" )
323
+ self .expect (self .tokens . OP , "]" )
303
324
a .addarc (z )
304
325
return a , z
305
326
else :
@@ -319,9 +340,9 @@ def parse_atom(self):
319
340
if self .value == "(" :
320
341
self .gettoken ()
321
342
a , z = self .parse_rhs ()
322
- self .expect (self .tokens [ 'OP' ] , ")" )
343
+ self .expect (self .tokens . OP , ")" )
323
344
return a , z
324
- elif self .type in (self .tokens [ ' NAME' ] , self .tokens [ ' STRING' ] ):
345
+ elif self .type in (self .tokens . NAME , self .tokens . STRING ):
325
346
a = NFAState ()
326
347
z = NFAState ()
327
348
a .addarc (z , self .value )
0 commit comments