class Parser
enum, struct, array, fixedlenarray, data<length>
Public Class Methods
new()
click to toggle source
# File lib/parser.rb, line 7 def initialize @definitions = {} @primitives = { "uint" => Bare.Uint, "int" => Bare.Int, "u8" => Bare.U8, "u16" => Bare.U16, "u32" => Bare.U32, "u64" => Bare.U64, "i8" => Bare.I8, "i16" => Bare.I16, "i32" => Bare.I32, "i64" => Bare.I64, "f32" => Bare.F32, "f64" => Bare.F64, "bool" => Bare.Bool, "string" => Bare.String, "data" => Bare.Data, "void" => Bare.Void, } end
Public Instance Methods
definitions()
click to toggle source
# File lib/parser.rb, line 29 def definitions @definitions end
parse(tokens)
click to toggle source
# File lib/parser.rb, line 87 def parse(tokens) while tokens.size > 0 if tokens[0] == "type" name = tokens[1] tokens, type = self.parse(tokens[2..tokens.size]) @definitions[name.to_sym] = type elsif tokens[0] == "map" raise SchemaParsingException.new("Map must be followed by a '[' eg. map[string]data") if tokens[1] != :open_brace tokens, map_from_type = parse(tokens[2..tokens.size]) raise SchemaParsingException.new("Map to type must be followed by a ']' eg. map[string]data") if tokens[0] != :close_brace tokens, map_to_type = parse(tokens[1..tokens.size]) return tokens, Bare.Map(map_from_type, map_to_type) elsif tokens[0] == "data" && tokens.size > 3 && tokens[1] == :less_than raise SchemaParsingException.new("data< must be followed by a number for a fixed sized bare data") unless tokens[2].is_a?(Numeric) raise SchemaParsingException.new("data<# must be followed by a >") unless tokens[3] == :greater_than return tokens[4..tokens.size], Bare.DataFixedLen(tokens[2]) elsif tokens[0] == "enum" name = tokens[1] raise SchemaParsingException.new("Enum must be followed by a '{'") if tokens[2] != :open_block tokens, enum = parse_enum(tokens[3..tokens.size]) @definitions[name.to_sym] = enum elsif tokens[0] == "optional" raise SchemaParsingException.new("Optional must be followed by a '< TYPE > you are missing the first <'") if tokens[1] != :less_than tokens, optional_type = self.parse(tokens[2..tokens.size]) raise SchemaParsingException.new("Optional must be followed by a '< TYPE >' you are missing the last >") if tokens[0] != :greater_than return tokens[1..tokens.size], Bare.Optional(optional_type) elsif tokens[0] == :open_brace if tokens[1].is_a?(Numeric) size = tokens[1] raise SchemaParsingException.new("Fixed Length Array size must be followed by a ']'") if tokens[2] != :close_brace tokens, arr_type = parse(tokens[3..tokens.size]) return tokens, Bare.ArrayFixedLen(arr_type, size) else tokens, arr_type = parse(tokens[2..tokens.size]) return tokens, Bare.Array(arr_type) end elsif tokens[0] == :open_paren tokens, union_hash = parse_union(tokens[1..tokens.size]) raise SchemaParsingException.new("Union must be followed by a ')'") if tokens[0] != :close_paren return tokens[1..tokens.size], Bare.Union(union_hash) elsif tokens[0] == :open_block tokens, struct_fields = parse_struct(tokens[1..tokens.size]) strct = Bare.Struct(struct_fields) return tokens, strct elsif @primitives.include?(tokens[0]) type = @primitives[tokens[0]] return tokens[1..tokens.size], type elsif @definitions.keys.include?(tokens[0].to_sym) # User defined type return tokens[1..tokens.size], @definitions[tokens[0].to_sym] elsif tokens[0].is_a?(String) && tokens[0][0].upcase == tokens[0][0] # Not yet defined user type return tokens[1..tokens.size], tokens[0].to_sym else raise SchemaParsingException.new("Unable to parse token: #{tokens[0]}") end end end
parse_enum(tokens)
click to toggle source
# File lib/parser.rb, line 33 def parse_enum(tokens) enum_hash = {} # {1 => "abc", 5 => :cow, 16382 => 123} count = 0 while tokens[0] != :close_block if tokens[1] == :equal name = tokens[0] int_repr = tokens[2] enum_hash[int_repr] = name tokens = tokens[3..tokens.size] else enum_hash[count] = tokens[0] count += 1 tokens = tokens[1..tokens.size] end end enum = Bare.Enum(enum_hash) return tokens[1..tokens.size], enum end
parse_struct(tokens)
click to toggle source
# File lib/parser.rb, line 77 def parse_struct(tokens) struct_fields = {} while tokens.size >= 2 and tokens[1] == :colon name = tokens[0] tokens, type = self.parse(tokens[2..tokens.size]) struct_fields[name.to_sym] = type end return tokens[1..tokens.size], struct_fields end
parse_union(tokens)
click to toggle source
# File lib/parser.rb, line 52 def parse_union(tokens) count = 0 union_hash = {} # type A_UNION ( int | uint | data = 7 | f32 ) while tokens[0] != :close_paren if tokens[0] == :bar tokens = tokens[1..tokens.size] else if tokens[1] == :equal raise SchemaParsingException.new("Equals sign in union must be followed by a number") unless tokens[2].is_a?(Numeric) count = tokens[2] tokens, type = self.parse(tokens) tokens = tokens[2..tokens.size] union_hash[count] = type count += 1 else tokens, type = self.parse(tokens) union_hash[count] = type count += 1 end end end return tokens, union_hash end