lib/rbs/parser.y in rbs-1.0.6 vs lib/rbs/parser.y in rbs-1.1.0
- old
+ new
@@ -758,12 +758,12 @@
}
| kLBRACKET kRBRACKET {
location = val[0].location + val[1].location
result = Types::Tuple.new(types: [], location: location)
}
- | kLBRACKET type_list kRBRACKET {
- location = val[0].location + val[2].location
+ | kLBRACKET type_list comma_opt kRBRACKET {
+ location = val[0].location + val[3].location
types = val[1]
result = Types::Tuple.new(types: types, location: location)
}
| kLPAREN type kRPAREN {
type = val[1].dup
@@ -792,22 +792,22 @@
| type_list kCOMMA type {
result = val[0] + [val[2]]
}
record_type:
- kLBRACE record_fields kRBRACE {
+ kLBRACE record_fields comma_opt kRBRACE {
result = Types::Record.new(
fields: val[1],
- location: val[0].location + val[2].location
+ location: val[0].location + val[3].location
)
}
record_fields:
record_field {
result = val[0]
}
- | record_field kCOMMA record_fields {
+ | record_fields kCOMMA record_field {
result = val[0].merge!(val[2])
}
record_field:
tSYMBOL kFATARROW type {
@@ -1060,10 +1060,14 @@
}
| tNAMESPACE {
namespace = Namespace.parse(val[0].value)
result = LocatedValue.new(value: namespace, location: val[0].location)
}
+
+ comma_opt:
+ kCOMMA | # empty
+
end
---- inner
Types = RBS::Types
@@ -1082,21 +1086,19 @@
@location = location
@value = value
end
end
-require "strscan"
-
attr_reader :input
attr_reader :buffer
attr_reader :eof_re
def initialize(type, buffer:, eof_re:)
super()
@type = type
@buffer = buffer
- @input = StringScanner.new(buffer.content)
+ @input = CharScanner.new(buffer.content)
@eof_re = eof_re
@eof = false
@bound_variables_stack = []
@comments = {}
@ascii_only = buffer.content.ascii_only?
@@ -1208,15 +1210,11 @@
[false, nil]
end
end
def charpos(scanner)
- if @ascii_only
- scanner.pos
- else
- scanner.charpos
- end
+ scanner.charpos
end
def empty_params_result
[
[],
@@ -1419,19 +1417,23 @@
new_token(:tSTRING, s)
when input.scan(/'(\\'|[^'])*'/)
s = input.matched.yield_self {|s| s[1, s.length - 2] }.gsub(/\\'/, "'")
new_token(:tSTRING, s)
else
- raise "Unexpected token: #{input.peek(10)}..."
+ text = input.peek(10)
+ start_index = charpos(input)
+ end_index = start_index + text.length
+ location = RBS::Location.new(buffer: buffer, start_pos: start_index, end_pos: end_index)
+ raise LexerError.new(input: text, location: location)
end
end
def on_error(token_id, error_value, value_stack)
raise SyntaxError.new(token_str: token_to_str(token_id), error_value: error_value, value_stack: value_stack)
end
-class SyntaxError < StandardError
+class SyntaxError < ParsingError
attr_reader :token_str, :error_value, :value_stack
def initialize(token_str:, error_value:, value_stack: nil)
@token_str = token_str
@error_value = error_value
@@ -1439,18 +1441,29 @@
super "parse error on value: #{error_value.inspect} (#{token_str})"
end
end
-class SemanticsError < StandardError
+class SemanticsError < ParsingError
attr_reader :subject, :location, :original_message
def initialize(message, subject:, location:)
@subject = subject
@location = location
@original_message = message
super "parse error on #{location}: #{message}"
+ end
+end
+
+class LexerError < ParsingError
+ attr_reader :location, :input
+
+ def initialize(input:, location:)
+ @input = input
+ @location = location
+
+ super "Unexpected string: #{input}..."
end
end
---- footer