Skip to content

Commit 94e75d7

Browse files
committed
Cleanup heredoc parsing by removing some duplicated lex code
1 parent 7deaaa6 commit 94e75d7

File tree

1 file changed

+49
-35
lines changed

1 file changed

+49
-35
lines changed

lib/opal/parser/lexer.rb

Lines changed: 49 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,48 @@ def read_escape
201201
end
202202
end
203203

204-
def next_string_token
204+
def peek_variable_name
205+
if check(/[@$]/)
206+
return :tSTRING_DVAR
207+
elsif scan(/\{/)
208+
return :tSTRING_DBEG
209+
end
210+
end
211+
212+
def here_document(str_parse)
213+
eos_regx = /[ \t]*#{Regexp.escape(str_parse[:end])}(\r*\n|$)/
214+
215+
if check(eos_regx)
216+
scan(/[ \t]*#{Regexp.escape(str_parse[:end])}/)
217+
218+
if str_parse[:scanner]
219+
@scanner_stack << str_parse[:scanner]
220+
@scanner = str_parse[:scanner]
221+
end
222+
223+
return :tSTRING_END
224+
end
225+
226+
str_buffer = []
227+
228+
if scan(/#/)
229+
if tok = peek_variable_name
230+
return tok
231+
end
232+
233+
str_buffer << '#'
234+
end
235+
236+
add_heredoc_content str_buffer, str_parse
237+
238+
complete_str = str_buffer.join ''
239+
@line += complete_str.count("\n")
240+
241+
self.yylval = complete_str
242+
return :tSTRING_CONTENT
243+
end
244+
245+
def parse_string
205246
str_parse = self.strterm
206247
scanner = @scanner
207248
space = false
@@ -215,21 +256,6 @@ def next_string_token
215256
# if not end of string, so we must be parsing contents
216257
str_buffer = []
217258

218-
if str_parse[:type] == :heredoc
219-
eos_regx = /[ \t]*#{Regexp.escape(str_parse[:end])}(\r*\n|$)/
220-
221-
if check(eos_regx)
222-
scan(/[ \t]*#{Regexp.escape(str_parse[:end])}/)
223-
224-
if str_parse[:scanner]
225-
@scanner_stack << str_parse[:scanner]
226-
@scanner = str_parse[:scanner]
227-
end
228-
229-
return :tSTRING_END
230-
end
231-
end
232-
233259
# see if we can read end of string/xstring/regexp markers
234260
# if scan /#{str_parse[:end]}/
235261
if scan Regexp.new(Regexp.escape(str_parse[:end]))
@@ -304,11 +330,7 @@ def next_string_token
304330
str_buffer << '#'
305331
end
306332

307-
if str_parse[:type] == :heredoc
308-
add_heredoc_content str_buffer, str_parse
309-
else
310-
add_string_content str_buffer, str_parse
311-
end
333+
add_string_content str_buffer, str_parse
312334

313335
complete_str = str_buffer.join ''
314336
@line += complete_str.count("\n")
@@ -339,19 +361,7 @@ def add_heredoc_content(str_buffer, str_parse)
339361
c = "\\" + scanner.matched
340362
end
341363
else
342-
c = if scan(/n/)
343-
"\n"
344-
elsif scan(/r/)
345-
"\r"
346-
elsif scan(/\n/)
347-
"\n"
348-
elsif scan(/t/)
349-
"\t"
350-
else
351-
# escaped char doesnt need escaping, so just return it
352-
scan(/./)
353-
scanner.matched
354-
end
364+
c = self.read_escape
355365
end
356366
else
357367
handled = false
@@ -564,7 +574,11 @@ def yylex
564574
c = ''
565575

566576
if self.strterm
567-
token = next_string_token
577+
if self.strterm[:type] == :heredoc
578+
token = here_document(self.strterm)
579+
else
580+
token = parse_string
581+
end
568582

569583
if token == :tSTRING_END or token == :tREGEXP_END
570584
self.strterm = nil

0 commit comments

Comments
 (0)