@@ -186,6 +186,8 @@ mutable struct ParseStream
186
186
lexer:: Tokenize.Lexers.Lexer{IOBuffer}
187
187
# Lookahead buffer for already lexed tokens
188
188
lookahead:: Vector{SyntaxToken}
189
+ # Pool of stream positions for use as working space in parsing
190
+ position_pool:: Vector{Vector{ParseStreamPosition}}
189
191
# Parser output as an ordered sequence of ranges, parent nodes after children.
190
192
ranges:: Vector{TaggedRange}
191
193
# Parsing diagnostics (errors/warnings etc)
@@ -210,6 +212,7 @@ mutable struct ParseStream
210
212
# like an acceptable tradeoff.
211
213
ver = (version. major, version. minor)
212
214
new (text_buf, text_root, lexer,
215
+ Vector {Vector{ParseStreamPosition}} (),
213
216
Vector {SyntaxToken} (),
214
217
Vector {TaggedRange} (),
215
218
Vector {Diagnostic} (),
@@ -268,6 +271,19 @@ function show_diagnostics(io::IO, stream::ParseStream, code)
268
271
show_diagnostics (io, stream. diagnostics, code)
269
272
end
270
273
274
+ # We manage a pool of stream positions as parser working space
275
+ function acquire_positions (stream)
276
+ if isempty (stream. position_pool)
277
+ return Vector {ParseStreamPosition} ()
278
+ end
279
+ pop! (stream. position_pool)
280
+ end
281
+
282
+ function release_positions (stream, positions)
283
+ empty! (positions)
284
+ push! (stream. position_pool, positions)
285
+ end
286
+
271
287
# -------------------------------------------------------------------------------
272
288
# Stream input interface - the peek_* family of functions
273
289
@@ -311,6 +327,11 @@ function _lookahead_index(stream::ParseStream, n::Integer, skip_newlines::Bool)
311
327
end
312
328
end
313
329
330
+ @noinline function _parser_stuck_error (stream)
331
+ # Optimization: emit unlikely errors in a separate function
332
+ error (" The parser seems stuck at byte $(stream. next_byte) " )
333
+ end
334
+
314
335
"""
315
336
peek(stream [, n=1]; skip_newlines=false)
316
337
@@ -333,7 +354,7 @@ function peek_token(stream::ParseStream, n::Integer=1;
333
354
skip_newlines= false , skip_whitespace= true )
334
355
stream. peek_count += 1
335
356
if stream. peek_count > 100_000
336
- error ( " The parser seems stuck at byte $( stream. next_byte) " )
357
+ _parser_stuck_error ( stream)
337
358
end
338
359
i = _lookahead_index (stream, n, skip_newlines)
339
360
if ! skip_whitespace
0 commit comments