Add support for terminating tokens
parent
2e2edd1908
commit
56eed66541
|
@ -6,7 +6,6 @@ require "./token"
|
||||||
# provided in the RFC and ensuring a correct functioning of the `CBOR::Lexer`.
|
# provided in the RFC and ensuring a correct functioning of the `CBOR::Lexer`.
|
||||||
class CBOR::Diagnostic
|
class CBOR::Diagnostic
|
||||||
@lexer : Lexer
|
@lexer : Lexer
|
||||||
@is_array : Bool = false
|
|
||||||
|
|
||||||
def initialize(input)
|
def initialize(input)
|
||||||
@lexer = Lexer.new(input)
|
@lexer = Lexer.new(input)
|
||||||
|
@ -29,17 +28,23 @@ class CBOR::Diagnostic
|
||||||
return nil unless token
|
return nil unless token
|
||||||
|
|
||||||
case token
|
case token
|
||||||
when Token::BytesArray
|
when Token::BytesArrayT
|
||||||
@is_array = true
|
consume_bytes_array
|
||||||
when Token::BreakT
|
else
|
||||||
@is_array = flase
|
Token.to_diagnostic(token)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
separator + Token.to_diagnostic(token)
|
private def consume_bytes_array : String
|
||||||
|
elements = [] of String
|
||||||
|
|
||||||
|
loop do
|
||||||
|
token = @lexer.next_token
|
||||||
|
raise "Unexpected EOF" unless token
|
||||||
|
break if token.is_a?(Token::BytesArrayEndT)
|
||||||
|
elements << Token.to_diagnostic(token)
|
||||||
end
|
end
|
||||||
|
|
||||||
private def separator : String
|
"(_ #{elements.join(", ")})"
|
||||||
return ", " if @is_array
|
|
||||||
""
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
require "./token"
|
require "./token"
|
||||||
|
|
||||||
class CBOR::Lexer
|
class CBOR::Lexer
|
||||||
BREAK = 0xff
|
|
||||||
|
|
||||||
def self.new(string : String)
|
def self.new(string : String)
|
||||||
new IO::Memory.new(string)
|
new IO::Memory.new(string)
|
||||||
end
|
end
|
||||||
|
@ -13,6 +11,10 @@ class CBOR::Lexer
|
||||||
|
|
||||||
@current_pos : Int64
|
@current_pos : Int64
|
||||||
@eof : Bool = false
|
@eof : Bool = false
|
||||||
|
# Holds a list of previously opened tokens.
|
||||||
|
# When a break in reached, the last entry in the array is
|
||||||
|
# the token to close.
|
||||||
|
@open_tokens = [] of Token::T
|
||||||
|
|
||||||
def initialize(@io : IO)
|
def initialize(@io : IO)
|
||||||
@current_pos = 0
|
@current_pos = 0
|
||||||
|
@ -60,10 +62,9 @@ class CBOR::Lexer
|
||||||
when 0x5b
|
when 0x5b
|
||||||
consume_binary(read(UInt64))
|
consume_binary(read(UInt64))
|
||||||
when 0x5f
|
when 0x5f
|
||||||
Token::BytesArrayStartT.new(@current_pos)
|
open_token(Token::BytesArrayT.new(@current_pos))
|
||||||
when 0xff
|
when 0xff
|
||||||
# TODO: Define which segment it's breaking
|
finish_token
|
||||||
Token::BreakT.new(@current_pos)
|
|
||||||
else
|
else
|
||||||
raise ParseError.new("Unexpected first byte 0x#{current_byte.to_s(16)}")
|
raise ParseError.new("Unexpected first byte 0x#{current_byte.to_s(16)}")
|
||||||
end
|
end
|
||||||
|
@ -89,6 +90,26 @@ class CBOR::Lexer
|
||||||
Token::BytesT.new(@current_pos, bytes)
|
Token::BytesT.new(@current_pos, bytes)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private def open_token(token : Token::T) : Token::T
|
||||||
|
@open_tokens.push(token)
|
||||||
|
token
|
||||||
|
end
|
||||||
|
|
||||||
|
private def finish_token : Token::T
|
||||||
|
opened_token = @open_tokens.pop
|
||||||
|
|
||||||
|
case opened_token
|
||||||
|
when Token::ArrayT
|
||||||
|
Token::ArrayEndT.new(@current_pos)
|
||||||
|
when Token::BytesArrayT
|
||||||
|
Token::BytesArrayEndT.new(@current_pos)
|
||||||
|
when Token::StringArrayT
|
||||||
|
Token::StringArrayEndT.new(@current_pos)
|
||||||
|
else
|
||||||
|
raise ParseError.new("Unexpected token termination #{opened_token.class}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Creates a method overloaded for each UInt sizes to convert the UInt into
|
# Creates a method overloaded for each UInt sizes to convert the UInt into
|
||||||
# the respective Int capable of containing the value
|
# the respective Int capable of containing the value
|
||||||
|
|
||||||
|
|
|
@ -3,28 +3,30 @@ class CBOR::Token
|
||||||
record UndefinedT, byte_number : Int64
|
record UndefinedT, byte_number : Int64
|
||||||
record BoolT, byte_number : Int64, value : Bool
|
record BoolT, byte_number : Int64, value : Bool
|
||||||
record ArrayT, byte_number : Int64, size : UInt32?
|
record ArrayT, byte_number : Int64, size : UInt32?
|
||||||
|
record ArrayEndT, byte_number : Int64
|
||||||
record MapT, byte_number : Int64, size : UInt32?
|
record MapT, byte_number : Int64, size : UInt32?
|
||||||
record IntT, byte_number : Int64, value : Int8 | UInt8 | Int16 | UInt16 | Int32 | UInt32 | Int64 | UInt64 | Int128
|
record IntT, byte_number : Int64, value : Int8 | UInt8 | Int16 | UInt16 | Int32 | UInt32 | Int64 | UInt64 | Int128
|
||||||
record FloatT, byte_number : Int64, value : Float64
|
record FloatT, byte_number : Int64, value : Float64
|
||||||
record StringT, byte_number : Int64, value : String
|
record StringT, byte_number : Int64, value : String
|
||||||
record BytesT, byte_number : Int64, value : Bytes
|
record BytesT, byte_number : Int64, value : Bytes
|
||||||
record StringArrayStartT, byte_number : Int64
|
record StringArrayT, byte_number : Int64
|
||||||
record StringArrayEndT, byte_number : Int64
|
record StringArrayEndT, byte_number : Int64
|
||||||
record BytesArrayStartT, byte_number : Int64
|
record BytesArrayT, byte_number : Int64
|
||||||
record BytesArrayEndT, byte_number : Int64
|
record BytesArrayEndT, byte_number : Int64
|
||||||
|
|
||||||
alias T = NullT |
|
alias T = NullT |
|
||||||
UndefinedT |
|
UndefinedT |
|
||||||
BoolT |
|
BoolT |
|
||||||
ArrayT |
|
ArrayT |
|
||||||
|
ArrayEndT |
|
||||||
MapT |
|
MapT |
|
||||||
IntT |
|
IntT |
|
||||||
FloatT |
|
FloatT |
|
||||||
StringT |
|
StringT |
|
||||||
BytesT |
|
BytesT |
|
||||||
StringArrayStartT |
|
StringArrayT |
|
||||||
StringArrayEndT |
|
StringArrayEndT |
|
||||||
BytesArrayStartT |
|
BytesArrayT |
|
||||||
BytesArrayEndT
|
BytesArrayEndT
|
||||||
|
|
||||||
def self.to_diagnostic(token : T) : String
|
def self.to_diagnostic(token : T) : String
|
||||||
|
@ -40,7 +42,7 @@ class CBOR::Token
|
||||||
"undefined"
|
"undefined"
|
||||||
when BoolT
|
when BoolT
|
||||||
token.value.to_s
|
token.value.to_s
|
||||||
when BytesArrayStartT
|
when BytesArrayT
|
||||||
"(_ "
|
"(_ "
|
||||||
when BytesArrayEndT
|
when BytesArrayEndT
|
||||||
")"
|
")"
|
||||||
|
|
Loading…
Reference in New Issue