11import os .path
22import 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
44
55from pegen import grammar
66from pegen .grammar import (
@@ -93,7 +93,7 @@ def visit_Forced(self, node: Forced) -> bool:
9393class PythonCallMakerVisitor (GrammarVisitor ):
9494 def __init__ (self , parser_generator : ParserGenerator ):
9595 self .gen = parser_generator
96- self .cache : Dict [Any , Any ] = {}
96+ self .cache : Dict [str , Tuple [ str , str ] ] = {}
9797
9898 def visit_NameLeaf (self , node : NameLeaf ) -> Tuple [Optional [str ], str ]:
9999 name = node .value
@@ -110,16 +110,6 @@ def visit_NameLeaf(self, node: NameLeaf) -> Tuple[Optional[str], str]:
110110 def visit_StringLeaf (self , node : StringLeaf ) -> Tuple [str , str ]:
111111 return "literal" , f"self.expect({ node .value } )"
112112
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-
123113 def visit_NamedItem (self , node : NamedItem ) -> Tuple [Optional [str ], str ]:
124114 name , call = self .visit (node .item )
125115 if node .name :
@@ -151,26 +141,57 @@ def visit_Opt(self, node: Opt) -> Tuple[str, str]:
151141 else :
152142 return "opt" , f"{ call } ,"
153143
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+
154172 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+ )
160179
161180 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+ )
167187
168188 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+ )
174195
175196 def visit_Group (self , node : Group ) -> Tuple [Optional [str ], str ]:
176197 return self .visit (node .rhs )
0 commit comments