diff --git a/lib/hjson/ast/nodes/any.rb b/lib/hjson/ast/nodes/any.rb index 29742c5..f335019 100644 --- a/lib/hjson/ast/nodes/any.rb +++ b/lib/hjson/ast/nodes/any.rb @@ -12,7 +12,7 @@ class Any < Node parser do if punctuator? - fail SyntaxError, 'Any value does not expected %p' % char + fail SyntaxError.new(self, ('Any value does not expect %p' % char)) end end parser do diff --git a/lib/hjson/ast/nodes/array.rb b/lib/hjson/ast/nodes/array.rb index 8b47a9f..9e9060a 100644 --- a/lib/hjson/ast/nodes/array.rb +++ b/lib/hjson/ast/nodes/array.rb @@ -18,7 +18,7 @@ class Array < Node end end end - parser { fail EndOfInputError } + parser { fail EndOfInputError.new(self) } end end end diff --git a/lib/hjson/ast/nodes/keyname.rb b/lib/hjson/ast/nodes/keyname.rb index 6dcec74..bff71d4 100644 --- a/lib/hjson/ast/nodes/keyname.rb +++ b/lib/hjson/ast/nodes/keyname.rb @@ -15,17 +15,17 @@ class Keyname < Node parser do until eos? if colon? - fail SyntaxError if payload.empty? + fail SyntaxError.new(self) if payload.empty? if positive?(space) && space != payload.length buffer.pos = start + space - fail SyntaxError + fail SyntaxError.new(self) end halt(payload) elsif char <= ' ' - fail SyntaxError if eos? + fail SyntaxError.new(self) if eos? self.space = payload.length if negative?(space) elsif punctuator? - fail SyntaxError + fail SyntaxError.new(self) else payload << char end diff --git a/lib/hjson/ast/nodes/multiline.rb b/lib/hjson/ast/nodes/multiline.rb index 51287da..ba2187b 100644 --- a/lib/hjson/ast/nodes/multiline.rb +++ b/lib/hjson/ast/nodes/multiline.rb @@ -24,7 +24,10 @@ class Multiline < Node parser do loop do - fail SyntaxError unless char + unless char + fail SyntaxError.new(self) + end + if single_quote? self.triple += 1 read diff --git a/lib/hjson/ast/nodes/object.rb b/lib/hjson/ast/nodes/object.rb index 06529d6..90ee43c 100644 --- a/lib/hjson/ast/nodes/object.rb +++ b/lib/hjson/ast/nodes/object.rb @@ -32,7 +32,7 @@ class Object < Node if without_braces? halt(payload) else - fail EndOfInputError + fail EndOfInputError.new(self) end end end diff --git a/lib/hjson/ast/nodes/string.rb b/lib/hjson/ast/nodes/string.rb index d7bd859..c24a144 100644 --- a/lib/hjson/ast/nodes/string.rb +++ b/lib/hjson/ast/nodes/string.rb @@ -20,7 +20,7 @@ class String < Node declare :payload, '' - parser { fail SyntaxError unless double_quote? } + parser { fail SyntaxError.new(self) unless double_quote? } parser do while read halt(read && payload) if double_quote? @@ -48,7 +48,7 @@ def read_escapee def read_unicode uffff = 4.times.reduce(0) do |i, _| read - fail SyntaxError unless hex? + fail SyntaxError.new(self) unless hex? hex = char.to_i(16) break if hex.infinite? i * 16 + hex diff --git a/lib/hjson/ast/parser.rb b/lib/hjson/ast/parser.rb index 8d7b5c2..e8c5e94 100644 --- a/lib/hjson/ast/parser.rb +++ b/lib/hjson/ast/parser.rb @@ -45,6 +45,10 @@ def initialize(buffer, **options) assign_declared_vars! end + def current_line_number + string[0..pos].count("\n") + 1 + end + private def assign_declared_vars! @@ -62,8 +66,10 @@ def assign_declared_vars! def validate(expected) current = current_char - fail SyntaxError, - "Expected %p instead of %p" % [expected, current] if expected && expected != current + + if expected && expected != current + fail SyntaxError.new(self, ("Expected %p instead of %p" % [expected, current])) + end end def halt(data = nil) diff --git a/lib/hjson/errors.rb b/lib/hjson/errors.rb index a5709e8..3b5bce5 100644 --- a/lib/hjson/errors.rb +++ b/lib/hjson/errors.rb @@ -1,5 +1,13 @@ module Hjson - Error = Class.new(StandardError) + class Error < StandardError + def initialize(parser, message = "") + message.prepend("L#{parser.current_line_number}:#{parser.charpos} ") + message.strip! + + super(message) + end + end + SyntaxError = Class.new(Error) EndOfInputError = Class.new(Error) end