Skip to content

Commit c6c771d

Browse files
committed
Fix up some minor parser incompatibilities
1 parent 76eeb04 commit c6c771d

File tree

7 files changed

+39
-15
lines changed

7 files changed

+39
-15
lines changed

bin/prism

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,14 +224,21 @@ module Prism
224224

225225
# bin/prism parser [source]
226226
def parser(argv)
227-
require "parser/current"
227+
require "parser/ruby33"
228228
source, filepath = read_source(argv)
229229

230+
buffer = Parser::Source::Buffer.new(filepath, 1)
231+
buffer.source = source
232+
230233
puts "Parser:"
231-
pp Parser::CurrentRuby.parse(source, filepath)
234+
parser_ast, _, parser_tokens = Parser::Ruby33.new.tokenize(buffer)
235+
pp parser_ast
236+
pp parser_tokens
232237

233238
puts "Prism:"
234-
pp Translation::Parser.parse(source, filepath)
239+
prism_ast, _, prism_tokens = Prism::Translation::Parser33.new.tokenize(buffer)
240+
pp prism_ast
241+
pp prism_tokens
235242
end
236243

237244
# bin/prism ripper [source]

lib/prism/translation.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ module Prism
55
# syntax trees.
66
module Translation # steep:ignore
77
autoload :Parser, "prism/translation/parser"
8+
autoload :Parser33, "prism/translation/parser33"
9+
autoload :Parser34, "prism/translation/parser34"
810
autoload :Ripper, "prism/translation/ripper"
911
autoload :RubyParser, "prism/translation/ruby_parser"
1012
end

lib/prism/translation/parser.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ def build_comments(comments, offset_cache)
168168

169169
# Build the parser gem tokens from the prism tokens.
170170
def build_tokens(tokens, offset_cache)
171-
Lexer.new(source_buffer, tokens.map(&:first), offset_cache).to_a
171+
Lexer.new(source_buffer, tokens, offset_cache).to_a
172172
end
173173

174174
# Build a range from a prism location.

lib/prism/translation/parser/lexer.rb

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -177,12 +177,23 @@ class Lexer
177177
WORDS_SEP: :tSPACE
178178
}
179179

180-
private_constant :TYPES
180+
# These constants represent flags in our lex state. We really, really
181+
# don't want to be using them and we really, really don't want to be
182+
# exposing them as part of our public API. Unfortunately, we don't have
183+
# another way of matching the exact tokens that the parser gem expects
184+
# without them. We should find another way to do this, but in the
185+
# meantime we'll hide them from the documentation and mark them as
186+
# private constants.
187+
EXPR_BEG = 0x1 # :nodoc:
188+
EXPR_LABEL = 0x400 # :nodoc:
189+
190+
private_constant :TYPES, :EXPR_BEG, :EXPR_LABEL
181191

182192
# The Parser::Source::Buffer that the tokens were lexed from.
183193
attr_reader :source_buffer
184194

185-
# An array of prism tokens that we lexed.
195+
# An array of tuples that contain prism tokens and their associated lex
196+
# state when they were lexed.
186197
attr_reader :lexed
187198

188199
# A hash that maps offsets in bytes to offsets in characters.
@@ -205,9 +216,9 @@ def to_a
205216
index = 0
206217

207218
while index < lexed.length
208-
token, = lexed[index]
219+
token, state = lexed[index]
209220
index += 1
210-
next if token.type == :IGNORED_NEWLINE || token.type == :EOF
221+
next if %i[IGNORED_NEWLINE __END__ EOF].include?(token.type)
211222

212223
type = TYPES.fetch(token.type)
213224
value = token.value
@@ -218,13 +229,13 @@ def to_a
218229
value.delete_prefix!("?")
219230
when :tCOMMENT
220231
if token.type == :EMBDOC_BEGIN
221-
until (next_token = lexed[index]) && next_token.type == :EMBDOC_END
232+
until (next_token = lexed[index][0]) && next_token.type == :EMBDOC_END
222233
value += next_token.value
223234
index += 1
224235
end
225236

226237
value += next_token.value
227-
location = Range.new(source_buffer, offset_cache[token.location.start_offset], offset_cache[lexed[index].location.end_offset])
238+
location = Range.new(source_buffer, offset_cache[token.location.start_offset], offset_cache[lexed[index][0].location.end_offset])
228239
index += 1
229240
else
230241
value.chomp!
@@ -247,6 +258,8 @@ def to_a
247258
value.chomp!(":")
248259
when :tLABEL_END
249260
value.chomp!(":")
261+
when :tLCURLY
262+
type = :tLBRACE if state == EXPR_BEG | EXPR_LABEL
250263
when :tNTH_REF
251264
value = Integer(value.delete_prefix("$"))
252265
when :tOP_ASGN
@@ -256,13 +269,13 @@ def to_a
256269
when :tSPACE
257270
value = nil
258271
when :tSTRING_BEG
259-
if ["\"", "'"].include?(value) && (next_token = lexed[index]) && next_token.type == :STRING_END
272+
if ["\"", "'"].include?(value) && (next_token = lexed[index][0]) && next_token.type == :STRING_END
260273
next_location = token.location.join(next_token.location)
261274
type = :tSTRING
262275
value = ""
263276
location = Range.new(source_buffer, offset_cache[next_location.start_offset], offset_cache[next_location.end_offset])
264277
index += 1
265-
elsif ["\"", "'"].include?(value) && (next_token = lexed[index]) && next_token.type == :STRING_CONTENT && (next_next_token = lexed[index + 1]) && next_next_token.type == :STRING_END
278+
elsif ["\"", "'"].include?(value) && (next_token = lexed[index][0]) && next_token.type == :STRING_CONTENT && (next_next_token = lexed[index + 1][0]) && next_next_token.type == :STRING_END
266279
next_location = token.location.join(next_next_token.location)
267280
type = :tSTRING
268281
value = next_token.value
@@ -280,7 +293,7 @@ def to_a
280293
location = Range.new(source_buffer, offset_cache[token.location.start_offset], offset_cache[token.location.start_offset + 1])
281294
end
282295
when :tSYMBEG
283-
if (next_token = lexed[index]) && next_token.type != :STRING_CONTENT && next_token.type != :EMBEXPR_BEGIN && next_token.type != :EMBVAR
296+
if (next_token = lexed[index][0]) && next_token.type != :STRING_CONTENT && next_token.type != :EMBEXPR_BEGIN && next_token.type != :EMBVAR
284297
next_location = token.location.join(next_token.location)
285298
type = :tSYMBOL
286299
value = next_token.value

lib/prism/translation/parser33.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
require_relative "parser"
1+
# frozen_string_literal: true
22

33
module Prism
44
module Translation

lib/prism/translation/parser34.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
require_relative "parser"
1+
# frozen_string_literal: true
22

33
module Prism
44
module Translation

test/prism/parser_test.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,11 @@ def test_warnings
101101

102102
parser = Prism::Translation::Parser33.new
103103
parser.diagnostics.all_errors_are_fatal = false
104+
104105
warning = nil
105106
parser.diagnostics.consumer = ->(received) { warning = received }
106107
parser.parse(buffer)
108+
107109
assert_equal :warning, warning.level
108110
assert_includes warning.message, "has been interpreted as"
109111
end

0 commit comments

Comments
 (0)