87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
# 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)
return tokens[1..tokens.size], tokens[0].to_sym
elsif tokens[0].is_a?(String) && tokens[0][0].upcase == tokens[0][0]
return tokens[1..tokens.size], tokens[0].to_sym
else
raise SchemaParsingException.new("Unable to parse token: #{tokens[0]}")
end
end
end
|