@@ -25,6 +25,14 @@ def _reset(self):
2525 self .current_char = None
2626 self .result = None
2727 self .stack = []
28+ self .completed = False
29+ self ._parsing_started = False
30+
31+ def _pop_stack (self , root_closed : bool = False ):
32+ """Pop from the parsing stack and mark completed only on an explicit root close."""
33+ self .stack .pop ()
34+ if root_closed and self ._parsing_started and not self .stack :
35+ self .completed = True
2836
2937 @staticmethod
3038 def parse_string (json_string ):
@@ -95,13 +103,17 @@ def _skip_multi_line_comment(self):
95103 self ._advance ()
96104
97105 def _parse (self ):
106+ if self .completed and not self .stack :
107+ return
98108 if self .result is None :
99109 self .result = self ._parse_value ()
100110 else :
101111 self ._continue_parsing ()
102112
103113 def _continue_parsing (self ):
104114 while self .current_char is not None :
115+ if self .completed and not self .stack :
116+ return
105117 if isinstance (self .result , dict ):
106118 self ._parse_object_content ()
107119 elif isinstance (self .result , list ):
@@ -114,7 +126,9 @@ def _continue_parsing(self):
114126 def _parse_value (self ):
115127 self ._skip_whitespace ()
116128 if self .current_char == "{" :
117- if self ._peek (1 ) == "{" : # Handle {{
129+ # Only treat doubled braces as a wrapper at the root; nested objects
130+ # must keep their closing braces paired correctly.
131+ if not self .stack and self ._peek (1 ) == "{" : # Handle {{
118132 self ._advance (2 )
119133 return self ._parse_object ()
120134 elif self .current_char == "[" :
@@ -153,21 +167,24 @@ def _parse_object(self):
153167 obj = {}
154168 self ._advance () # Skip opening brace
155169 self .stack .append (obj )
170+ self ._parsing_started = True
156171 self ._parse_object_content ()
157172 return obj
158173
159174 def _parse_object_content (self ):
160175 while self .current_char is not None :
161176 self ._skip_whitespace ()
162177 if self .current_char == "}" :
163- if self ._peek (1 ) == "}" : # Handle }}
178+ # Root-level wrapper outputs may end in "}}"; nested objects must
179+ # still close one brace at a time.
180+ if len (self .stack ) == 1 and self ._peek (1 ) == "}" : # Handle }}
164181 self ._advance (2 )
165182 else :
166183 self ._advance ()
167- self .stack . pop ( )
184+ self ._pop_stack ( root_closed = True )
168185 return
169186 if self .current_char is None :
170- self .stack . pop ()
187+ self ._pop_stack ()
171188 return # End of input reached while parsing object
172189
173190 key = self ._parse_key ()
@@ -190,7 +207,7 @@ def _parse_object_content(self):
190207 continue
191208 elif self .current_char != "}" :
192209 if self .current_char is None :
193- self .stack . pop ()
210+ self ._pop_stack ()
194211 return # End of input reached after value
195212 continue
196213
@@ -216,6 +233,7 @@ def _parse_array(self):
216233 arr = []
217234 self ._advance () # Skip opening bracket
218235 self .stack .append (arr )
236+ self ._parsing_started = True
219237 self ._parse_array_content ()
220238 return arr
221239
@@ -224,7 +242,7 @@ def _parse_array_content(self):
224242 self ._skip_whitespace ()
225243 if self .current_char == "]" :
226244 self ._advance ()
227- self .stack . pop ( )
245+ self ._pop_stack ( root_closed = True )
228246 return
229247 value = self ._parse_value ()
230248 self .stack [- 1 ].append (value )
@@ -236,10 +254,10 @@ def _parse_array_content(self):
236254 if self .current_char is None or self .current_char == "]" :
237255 if self .current_char == "]" :
238256 self ._advance ()
239- self .stack . pop ( )
257+ self ._pop_stack ( root_closed = True )
240258 return
241259 elif self .current_char != "]" :
242- self .stack . pop ()
260+ self ._pop_stack ()
243261 return
244262
245263 def _parse_string (self ):
0 commit comments