bare-rb 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/bare-rb.rb +10 -0
- data/lib/exceptions.rb +7 -0
- data/lib/lexer.rb +62 -0
- data/lib/parser.rb +102 -0
- data/lib/types.rb +2 -3
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bdfcd51a2a757a2cb2c532d1281afe227150518a6feb625466a5f25fac16b84b
|
4
|
+
data.tar.gz: ca3ed0f25556c996c62ff70a31ef3c50d9a3e6cad0d712eb8e428013a5af0af3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 222f83030bee145a42b3ae2ef890316f4969502f3a8e9704e3b84ffadaab0866d71163bf97b0d3f90ec02a065336343b20149375b9e628c646d8b342d0e5b27d
|
7
|
+
data.tar.gz: e757dbf048dd0f65392561a9034b3407d2fe9e2e942bcf181b3c7a25847a03e9eb515b66ef74b23115b37a94751daeae04eb4190b218a0c2dcbe2ab988ca3256
|
data/lib/bare-rb.rb
CHANGED
@@ -1,7 +1,17 @@
|
|
1
1
|
require 'set'
|
2
2
|
require_relative "types"
|
3
|
+
require_relative "lexer"
|
4
|
+
require_relative "parser"
|
3
5
|
|
4
6
|
class Bare
|
7
|
+
|
8
|
+
def self.parse_schema(path)
|
9
|
+
# Hash of class names to BARE ASTs
|
10
|
+
# Eg. types['Customer'] == Bare.i32
|
11
|
+
types = parser(lexer(path))
|
12
|
+
return types
|
13
|
+
end
|
14
|
+
|
5
15
|
def self.encode(msg, schema)
|
6
16
|
return schema.encode(msg)
|
7
17
|
end
|
data/lib/exceptions.rb
CHANGED
@@ -1,9 +1,16 @@
|
|
1
|
+
|
1
2
|
class BareException < StandardError
|
2
3
|
def initialize(msg=nil)
|
3
4
|
super
|
4
5
|
end
|
5
6
|
end
|
6
7
|
|
8
|
+
class SchemaParsingException < BareException
|
9
|
+
def initialize(msg=nil)
|
10
|
+
super
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
7
14
|
class VoidUsedOutsideTaggedSet < BareException
|
8
15
|
def initialize(msg = "Any type which is ultimately a void type (either directly or through user-defined types) may not be used as an optional type, struct member, array member, or map key or value. Void types may only be used as members of the set of types in a tagged union.")
|
9
16
|
super
|
data/lib/lexer.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require_relative './exceptions'
|
2
|
+
|
3
|
+
def lexer(path)
|
4
|
+
tokens = []
|
5
|
+
line_num = 0
|
6
|
+
File.open(path).each do |line|
|
7
|
+
while line.size > 0
|
8
|
+
if /^#/.match(line)
|
9
|
+
break
|
10
|
+
elsif /^\n/.match(line)
|
11
|
+
break
|
12
|
+
elsif /^ /.match(line)
|
13
|
+
line = line[1..]
|
14
|
+
elsif /^</.match(line)
|
15
|
+
line = line[1..]
|
16
|
+
tokens << :less_than
|
17
|
+
elsif /^>/.match(line)
|
18
|
+
line = line[1..]
|
19
|
+
tokens << :greater_than
|
20
|
+
next
|
21
|
+
elsif /^{/.match(line)
|
22
|
+
line = line[1..]
|
23
|
+
tokens << :open_block
|
24
|
+
elsif /^=/.match(line)
|
25
|
+
line = line[1..]
|
26
|
+
tokens << :equal
|
27
|
+
elsif /^}/.match(line)
|
28
|
+
line = line[1..]
|
29
|
+
tokens << :close_block
|
30
|
+
elsif /^\[/.match(line)
|
31
|
+
line = line[1..]
|
32
|
+
tokens << :open_brace
|
33
|
+
elsif /^\]/.match(line)
|
34
|
+
line = line[1..]
|
35
|
+
tokens << :close_brace
|
36
|
+
elsif /^\(/.match(line)
|
37
|
+
line = line[1..]
|
38
|
+
tokens << :open_paren
|
39
|
+
elsif /^\)/.match(line)
|
40
|
+
line = line[1..]
|
41
|
+
tokens << :close_paren
|
42
|
+
elsif /^\|/.match(line)
|
43
|
+
line = line[1..]
|
44
|
+
tokens << :bar
|
45
|
+
elsif match = /^([0-9]+)/.match(line)
|
46
|
+
tokens << match[0].to_i
|
47
|
+
line = line[(match.size + 1)..]
|
48
|
+
next
|
49
|
+
elsif match = /^[a-z,A-Z,_][_,a-z,A-Z,0-9]+/.match(line)
|
50
|
+
tokens << match[0]
|
51
|
+
line = line[(match[0].size)..]
|
52
|
+
elsif /:/.match(line)
|
53
|
+
tokens << :colon
|
54
|
+
line = line[1..]
|
55
|
+
else
|
56
|
+
raise SchemaParsingException.new("Unable to lex line #{line_num} near #{line.inspect}")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
line_num += 1
|
60
|
+
end
|
61
|
+
return tokens
|
62
|
+
end
|
data/lib/parser.rb
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
require_relative './exceptions'
|
2
|
+
|
3
|
+
|
4
|
+
# enum, struct, array, fixedlenarray, data<length>
|
5
|
+
class Parser
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@definitions = {}
|
9
|
+
@primitives = {
|
10
|
+
"uint" => Bare.Uint,
|
11
|
+
"int" => Bare.Int,
|
12
|
+
"u8" => Bare.U8,
|
13
|
+
"u16" => Bare.U16,
|
14
|
+
"u32" => Bare.U32,
|
15
|
+
"u64" => Bare.U64,
|
16
|
+
"i8" => Bare.I8,
|
17
|
+
"i16" => Bare.I16,
|
18
|
+
"i32" => Bare.I32,
|
19
|
+
"i64" => Bare.I64,
|
20
|
+
"f32" => Bare.F32,
|
21
|
+
"f64" => Bare.F64,
|
22
|
+
"bool" => Bare.Bool,
|
23
|
+
"string" => Bare.String,
|
24
|
+
"data" => Bare.Data,
|
25
|
+
"void" => Bare.Void,
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def definitions
|
30
|
+
@definitions
|
31
|
+
end
|
32
|
+
|
33
|
+
def parse_enum(tokens)
|
34
|
+
enum_hash = {} # {1 => "abc", 5 => :cow, 16382 => 123}
|
35
|
+
count = 0
|
36
|
+
while tokens[0] != :close_block
|
37
|
+
if tokens[1] == :equal
|
38
|
+
name = tokens[0]
|
39
|
+
int_repr = tokens[2]
|
40
|
+
enum_hash[int_repr] = name
|
41
|
+
tokens = tokens[3..]
|
42
|
+
else
|
43
|
+
enum_hash[count] = tokens[0]
|
44
|
+
count += 1
|
45
|
+
tokens = tokens[1..]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
enum = Bare.Enum(enum_hash)
|
49
|
+
return tokens[1..], enum
|
50
|
+
end
|
51
|
+
|
52
|
+
def parse_struct(tokens)
|
53
|
+
struct_fields = {}
|
54
|
+
while tokens.size >= 2 and tokens[1] == :colon
|
55
|
+
name = tokens[0]
|
56
|
+
tokens, type = self.parse(tokens[2..])
|
57
|
+
struct_fields[name.to_sym] = type
|
58
|
+
end
|
59
|
+
return tokens[1..], struct_fields
|
60
|
+
end
|
61
|
+
|
62
|
+
def parse(tokens)
|
63
|
+
while tokens.size > 0
|
64
|
+
if tokens[0] == "type"
|
65
|
+
name = tokens[1]
|
66
|
+
tokens, type = self.parse(tokens[2..])
|
67
|
+
@definitions[name.to_sym] = type
|
68
|
+
elsif tokens[0] == "map"
|
69
|
+
raise SchemaParsingException("Map must be followed by a '[' eg. map[string]data") if tokens[1] != :open_brace
|
70
|
+
tokens, map_from_type = parse(tokens[2..])
|
71
|
+
raise SchemaParsingException("Map to type must be followed by a ']' eg. map[string]data") if tokens[0] != :close_brace
|
72
|
+
tokens, map_to_type = parse(tokens[1..])
|
73
|
+
return tokens, Bare.Map(map_from_type,map_to_type)
|
74
|
+
elsif tokens[0] == "enum"
|
75
|
+
name = tokens[1]
|
76
|
+
raise SchemaParsingException("Enum must be followed by a '{'") if tokens[2] != :open_block
|
77
|
+
tokens, enum = parse_enum(tokens[3..])
|
78
|
+
@definitions[name.to_sym] = enum
|
79
|
+
return tokens, enum
|
80
|
+
elsif tokens[0] == :open_brace
|
81
|
+
tokens, arr_type = parse(tokens[2..])
|
82
|
+
return tokens, Bare.Array(arr_type)
|
83
|
+
elsif tokens[0] == :open_block
|
84
|
+
tokens, struct_fields = parse_struct(tokens[1..])
|
85
|
+
strct = Bare.Struct(struct_fields)
|
86
|
+
return tokens, strct
|
87
|
+
elsif @primitives.include?(tokens[0])
|
88
|
+
type = @primitives[tokens[0]]
|
89
|
+
return tokens[1..], type
|
90
|
+
else
|
91
|
+
raise SchemaParsingException.new("Unable to parse token: #{tokens[0]}")
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
def parser(tokens, definitions = {})
|
99
|
+
parser = Parser.new
|
100
|
+
parser.parse(tokens)
|
101
|
+
return parser.definitions
|
102
|
+
end
|
data/lib/types.rb
CHANGED
@@ -148,7 +148,6 @@ class BareTypes
|
|
148
148
|
key = output[:value]
|
149
149
|
output = @to.decode(output[:rest])
|
150
150
|
hash[key] = output[:value]
|
151
|
-
hash[key] = output[:value]
|
152
151
|
end
|
153
152
|
return {value: hash, rest: output[:rest]}
|
154
153
|
end
|
@@ -236,7 +235,7 @@ class BareTypes
|
|
236
235
|
output = Uint.new.decode(msg)
|
237
236
|
rest = output[:rest]
|
238
237
|
dataSize = output[:value]
|
239
|
-
return {value: rest[0..dataSize], rest: rest[dataSize..
|
238
|
+
return {value: rest[0..dataSize-1], rest: rest[dataSize..]}
|
240
239
|
end
|
241
240
|
end
|
242
241
|
|
@@ -506,7 +505,7 @@ class BareTypes
|
|
506
505
|
@valToInt = {}
|
507
506
|
raise BareException("Enum must initialized with a hash from integers to anything") if !source.is_a?(Hash)
|
508
507
|
raise BareException("Enum must have unique positive integer assignments") if Set.new(source.keys).size != source.keys.size
|
509
|
-
raise
|
508
|
+
raise EnumValueError("Enum must have unique values") if source.values.to_set.size != source.values.size
|
510
509
|
source.each do |k, v|
|
511
510
|
raise("Enum keys must be positive integers") if k < 0
|
512
511
|
@intToVal[k.to_i] = v
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bare-rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nate Tracy-Amoroso
|
@@ -10,7 +10,8 @@ bindir: bin
|
|
10
10
|
cert_chain: []
|
11
11
|
date: 2020-10-13 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
|
-
description:
|
13
|
+
description: The first implementation of the BARE (Binary Application Record Encoding)
|
14
|
+
in Ruby. Includes schema parsing!
|
14
15
|
email: n8@u.northwestern.edu
|
15
16
|
executables: []
|
16
17
|
extensions: []
|
@@ -18,6 +19,8 @@ extra_rdoc_files: []
|
|
18
19
|
files:
|
19
20
|
- "./lib/bare-rb.rb"
|
20
21
|
- "./lib/exceptions.rb"
|
22
|
+
- "./lib/lexer.rb"
|
23
|
+
- "./lib/parser.rb"
|
21
24
|
- "./lib/types.rb"
|
22
25
|
homepage: https://github.com/n8ta/bare-rb
|
23
26
|
licenses:
|