1
1
import os .path
2
2
import token
3
- from typing import IO , Any , Dict , Optional , Sequence , Set , Text , Tuple
3
+ from typing import IO , Any , Callable , Dict , Optional , Sequence , Set , Text , Tuple
4
4
5
5
from pegen import grammar
6
6
from pegen .grammar import (
@@ -93,7 +93,7 @@ def visit_Forced(self, node: Forced) -> bool:
93
93
class PythonCallMakerVisitor (GrammarVisitor ):
94
94
def __init__ (self , parser_generator : ParserGenerator ):
95
95
self .gen = parser_generator
96
- self .cache : Dict [Any , Any ] = {}
96
+ self .cache : Dict [str , Tuple [ str , str ] ] = {}
97
97
98
98
def visit_NameLeaf (self , node : NameLeaf ) -> Tuple [Optional [str ], str ]:
99
99
name = node .value
@@ -110,16 +110,6 @@ def visit_NameLeaf(self, node: NameLeaf) -> Tuple[Optional[str], str]:
110
110
def visit_StringLeaf (self , node : StringLeaf ) -> Tuple [str , str ]:
111
111
return "literal" , f"self.expect({ node .value } )"
112
112
113
- def visit_Rhs (self , node : Rhs ) -> Tuple [Optional [str ], str ]:
114
- if node in self .cache :
115
- return self .cache [node ]
116
- if len (node .alts ) == 1 and len (node .alts [0 ].items ) == 1 :
117
- self .cache [node ] = self .visit (node .alts [0 ].items [0 ])
118
- else :
119
- name = self .gen .artificial_rule_from_rhs (node )
120
- self .cache [node ] = name , f"self.{ name } ()"
121
- return self .cache [node ]
122
-
123
113
def visit_NamedItem (self , node : NamedItem ) -> Tuple [Optional [str ], str ]:
124
114
name , call = self .visit (node .item )
125
115
if node .name :
@@ -151,26 +141,57 @@ def visit_Opt(self, node: Opt) -> Tuple[str, str]:
151
141
else :
152
142
return "opt" , f"{ call } ,"
153
143
144
+ def _generate_artificial_rule_call (
145
+ self ,
146
+ node : Any ,
147
+ prefix : str ,
148
+ call_by_name_func : Callable [[str ], str ],
149
+ rule_generation_func : Callable [[], str ],
150
+ ) -> Tuple [str , str ]:
151
+ node_str = f"{ node } "
152
+ key = f"{ prefix } _{ node_str } "
153
+ if key in self .cache :
154
+ return self .cache [key ]
155
+
156
+ name = rule_generation_func ()
157
+ call = call_by_name_func (name )
158
+ self .cache [key ] = name , call
159
+ return self .cache [key ]
160
+
161
+ def visit_Rhs (self , node : Rhs ) -> Tuple [str , str ]:
162
+ if len (node .alts ) == 1 and len (node .alts [0 ].items ) == 1 :
163
+ return self .visit (node .alts [0 ].items [0 ])
164
+
165
+ return self ._generate_artificial_rule_call (
166
+ node ,
167
+ "rhs" ,
168
+ lambda name : f"self.{ name } ()" ,
169
+ lambda : self .gen .artificial_rule_from_rhs (node ),
170
+ )
171
+
154
172
def visit_Repeat0 (self , node : Repeat0 ) -> Tuple [str , str ]:
155
- if node in self .cache :
156
- return self .cache [node ]
157
- name = self .gen .artificial_rule_from_repeat (node .node , False )
158
- self .cache [node ] = name , f"self.{ name } ()," # Also a trailing comma!
159
- return self .cache [node ]
173
+ return self ._generate_artificial_rule_call (
174
+ node ,
175
+ "repeat0" ,
176
+ lambda name : f"self.{ name } ()," , # Also a trailing comma!
177
+ lambda : self .gen .artificial_rule_from_repeat (node .node , is_repeat1 = False ),
178
+ )
160
179
161
180
def visit_Repeat1 (self , node : Repeat1 ) -> Tuple [str , str ]:
162
- if node in self .cache :
163
- return self .cache [node ]
164
- name = self .gen .artificial_rule_from_repeat (node .node , True )
165
- self .cache [node ] = name , f"self.{ name } ()" # But no trailing comma here!
166
- return self .cache [node ]
181
+ return self ._generate_artificial_rule_call (
182
+ node ,
183
+ "repeat1" ,
184
+ lambda name : f"self.{ name } ()" , # But no trailing comma here!
185
+ lambda : self .gen .artificial_rule_from_repeat (node .node , is_repeat1 = True ),
186
+ )
167
187
168
188
def visit_Gather (self , node : Gather ) -> Tuple [str , str ]:
169
- if node in self .cache :
170
- return self .cache [node ]
171
- name = self .gen .artificial_rule_from_gather (node )
172
- self .cache [node ] = name , f"self.{ name } ()" # No trailing comma here either!
173
- return self .cache [node ]
189
+ return self ._generate_artificial_rule_call (
190
+ node ,
191
+ "gather" ,
192
+ lambda name : f"self.{ name } ()" , # No trailing comma here either!
193
+ lambda : self .gen .artificial_rule_from_gather (node ),
194
+ )
174
195
175
196
def visit_Group (self , node : Group ) -> Tuple [Optional [str ], str ]:
176
197
return self .visit (node .rhs )
0 commit comments