kdl 2.0.2 → 2.1.0
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/kdl/builder.rb +76 -0
- data/lib/kdl/document.rb +5 -1
- data/lib/kdl/error.rb +18 -5
- data/lib/kdl/kdl.yy +2 -2
- data/lib/kdl/node.rb +4 -0
- data/lib/kdl/parser_common.rb +5 -1
- data/lib/kdl/tokenizer.rb +10 -16
- data/lib/kdl/v1/kdl.yy +2 -2
- data/lib/kdl/v1/value.rb +1 -1
- data/lib/kdl/value.rb +1 -1
- data/lib/kdl/version.rb +1 -1
- data/lib/kdl.rb +22 -7
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 24483470a3eb179aeb4a3e2e759693a4e818316cb7cb6c3b019b22b2318504af
|
4
|
+
data.tar.gz: 73ce32af9afa6ebcd4be7a73add2ee1077e08aad71425863b75b1581613a2628
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b2ea10129c13825376583228ce0d5e91f888c89e6adb0787f02c1f046801d79809b0fa2997799b30237493b70717c1bc5423eefc360d07387333709157f6690b
|
7
|
+
data.tar.gz: fbbf3d6e8d148ab9a67855ed8751d31b1f28adc1a4798309c6dc6344d02042c655997ab9abfe833b32686f58cc1fb9da4024bb56e62794d14c7b0c1b201fedc4
|
data/lib/kdl/builder.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KDL
|
4
|
+
class Builder < BasicObject
|
5
|
+
class Error < ::KDL::Error; end
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@nesting = []
|
9
|
+
@document = Document.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def document(&block)
|
13
|
+
yield if block
|
14
|
+
@document
|
15
|
+
end
|
16
|
+
|
17
|
+
def node(name = nil, *args, type: nil, **props, &block)
|
18
|
+
n = Node.new(name&.to_s || "node", type:)
|
19
|
+
@nesting << n
|
20
|
+
args.each do |value|
|
21
|
+
case value
|
22
|
+
when ::Hash
|
23
|
+
value.each { |k, v| prop k, v }
|
24
|
+
else arg value
|
25
|
+
end
|
26
|
+
end
|
27
|
+
props.each do |key, value|
|
28
|
+
prop key, value
|
29
|
+
end
|
30
|
+
yield if block
|
31
|
+
@nesting.pop
|
32
|
+
if parent = current_node
|
33
|
+
parent.children << n
|
34
|
+
else
|
35
|
+
@document << n
|
36
|
+
end
|
37
|
+
n
|
38
|
+
end
|
39
|
+
alias _ node
|
40
|
+
|
41
|
+
def arg(value, type: nil)
|
42
|
+
if n = current_node
|
43
|
+
val = Value.from(value)
|
44
|
+
val = val.as_type(type) if type
|
45
|
+
n.arguments << val
|
46
|
+
val
|
47
|
+
else
|
48
|
+
raise Error, "Can't do argument, not inside Node"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def prop(key, value, type: nil)
|
53
|
+
key = key.to_s
|
54
|
+
if n = current_node
|
55
|
+
val = Value.from(value)
|
56
|
+
val = val.as_type(type) if type
|
57
|
+
n.properties[key] = val
|
58
|
+
val
|
59
|
+
else
|
60
|
+
raise Error, "Can't do property, not inside Node"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def method_missing(name, *args, **props, &block)
|
65
|
+
node name, *args, **props, &block
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def current_node
|
71
|
+
return nil if @nesting.empty?
|
72
|
+
|
73
|
+
@nesting.last
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/kdl/document.rb
CHANGED
@@ -6,7 +6,7 @@ module KDL
|
|
6
6
|
|
7
7
|
attr_accessor :nodes
|
8
8
|
|
9
|
-
def initialize(nodes)
|
9
|
+
def initialize(nodes = [])
|
10
10
|
@nodes = nodes
|
11
11
|
end
|
12
12
|
|
@@ -21,6 +21,10 @@ module KDL
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
+
def <<(node)
|
25
|
+
nodes << node
|
26
|
+
end
|
27
|
+
|
24
28
|
def arg(key)
|
25
29
|
self[key]&.arguments&.first&.value
|
26
30
|
end
|
data/lib/kdl/error.rb
CHANGED
@@ -1,13 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module KDL
|
4
|
-
class Error < StandardError
|
4
|
+
class Error < StandardError
|
5
|
+
attr_reader :filename, :line, :column
|
6
|
+
|
7
|
+
def initialize(message, filename = nil, line = nil, column = nil)
|
8
|
+
message += " (#{line}:#{column})" if line
|
9
|
+
message = "#{[filename, line, column].compact.join(':')}: #{message}" if filename
|
10
|
+
super(message)
|
11
|
+
@filename = filename
|
12
|
+
@line = line
|
13
|
+
@column = column
|
14
|
+
end
|
15
|
+
end
|
5
16
|
|
6
17
|
class VersionMismatchError < Error
|
7
18
|
attr_reader :version, :parser_version
|
8
19
|
|
9
|
-
def initialize(message, version = nil, parser_version = nil)
|
10
|
-
super(message)
|
20
|
+
def initialize(message, version = nil, parser_version = nil, filename = nil)
|
21
|
+
super(message, filename, 1, 1)
|
11
22
|
@version = version
|
12
23
|
@parser_version = parser_version
|
13
24
|
end
|
@@ -16,9 +27,11 @@ module KDL
|
|
16
27
|
class UnsupportedVersionError < Error
|
17
28
|
attr_reader :version
|
18
29
|
|
19
|
-
def initialize(message, version = nil)
|
20
|
-
super(message)
|
30
|
+
def initialize(message, version = nil, filename = nil)
|
31
|
+
super(message, filename, 1, 1)
|
21
32
|
@version = version
|
22
33
|
end
|
23
34
|
end
|
35
|
+
|
36
|
+
class ParseError < Error; end
|
24
37
|
end
|
data/lib/kdl/kdl.yy
CHANGED
data/lib/kdl/node.rb
CHANGED
data/lib/kdl/parser_common.rb
CHANGED
@@ -21,8 +21,12 @@ module KDL
|
|
21
21
|
def check_version
|
22
22
|
return unless doc_version = @tokenizer.version_directive
|
23
23
|
if doc_version != parser_version
|
24
|
-
raise VersionMismatchError.new("
|
24
|
+
raise VersionMismatchError.new("version mismatch, document specified v#{doc_version}, but this is a v#{parser_version} parser", doc_version, parser_version)
|
25
25
|
end
|
26
26
|
end
|
27
|
+
|
28
|
+
def on_error(t, val, vstack)
|
29
|
+
raise KDL::ParseError.new("unexpected #{token_to_str(t)} #{val&.value.inspect}", @tokenizer.filename, val&.line, val&.column)
|
30
|
+
end
|
27
31
|
end
|
28
32
|
end
|
data/lib/kdl/tokenizer.rb
CHANGED
@@ -4,12 +4,6 @@ require 'bigdecimal'
|
|
4
4
|
|
5
5
|
module KDL
|
6
6
|
class Tokenizer
|
7
|
-
class Error < ::KDL::Error
|
8
|
-
def initialize(message, line, column)
|
9
|
-
super("#{message} (#{line}:#{column})")
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
7
|
class Token
|
14
8
|
attr_reader :type, :value, :line, :column, :meta
|
15
9
|
|
@@ -30,10 +24,9 @@ module KDL
|
|
30
24
|
def to_s
|
31
25
|
"#{value.inspect} (#{line}:#{column})"
|
32
26
|
end
|
33
|
-
alias inspect to_s
|
34
27
|
end
|
35
28
|
|
36
|
-
attr_reader :index
|
29
|
+
attr_reader :index, :filename
|
37
30
|
|
38
31
|
SYMBOLS = {
|
39
32
|
'{' => :LBRACE,
|
@@ -72,13 +65,14 @@ module KDL
|
|
72
65
|
|
73
66
|
VERSION_PATTERN = /\A\/-[#{WHITESPACE.join}]*kdl-version[#{WHITESPACE.join}]+(\d+)[#{WHITESPACE.join}]*[#{NEWLINES.join}]/
|
74
67
|
|
75
|
-
def initialize(str, start = 0)
|
68
|
+
def initialize(str, start = 0, filename: nil)
|
76
69
|
@str = debom(str)
|
77
|
-
@context = nil
|
78
|
-
@rawstring_hashes = nil
|
79
70
|
@start = start
|
80
71
|
@index = start
|
81
72
|
@buffer = +""
|
73
|
+
@filename = filename
|
74
|
+
@context = nil
|
75
|
+
@rawstring_hashes = nil
|
82
76
|
@done = false
|
83
77
|
@previous_context = nil
|
84
78
|
@line = 1
|
@@ -201,7 +195,7 @@ module KDL
|
|
201
195
|
traverse(1)
|
202
196
|
end
|
203
197
|
when '\\'
|
204
|
-
t = Tokenizer.new(@str, @index + 1)
|
198
|
+
t = Tokenizer.new(@str, @index + 1, filename:)
|
205
199
|
la = t.next_token
|
206
200
|
if la[0] == :NEWLINE || la[0] == :EOF || (la[0] == :WS && (lan = t.next_token[0]) == :NEWLINE || lan == :EOF)
|
207
201
|
traverse_to(t.index)
|
@@ -433,7 +427,7 @@ module KDL
|
|
433
427
|
@comment_nesting = 1
|
434
428
|
traverse(2)
|
435
429
|
elsif c == "\\"
|
436
|
-
t = Tokenizer.new(@str, @index + 1)
|
430
|
+
t = Tokenizer.new(@str, @index + 1, filename:)
|
437
431
|
la = t.next_token
|
438
432
|
if la[0] == :NEWLINE || la[0] == :EOF || (la[0] == :WS && (lan = t.next_token[0]) == :NEWLINE || lan == :EOF)
|
439
433
|
traverse_to(t.index)
|
@@ -446,7 +440,7 @@ module KDL
|
|
446
440
|
return token(:WS, -@buffer)
|
447
441
|
end
|
448
442
|
when :equals
|
449
|
-
t = Tokenizer.new(@str, @index)
|
443
|
+
t = Tokenizer.new(@str, @index, filename:)
|
450
444
|
la = t.next_token
|
451
445
|
if la[0] == :WS
|
452
446
|
@buffer << la[1].value
|
@@ -488,9 +482,9 @@ module KDL
|
|
488
482
|
|
489
483
|
def raise_error(error)
|
490
484
|
case error
|
491
|
-
when String then raise
|
485
|
+
when String then raise ParseError.new(error, @filename, @line, @column)
|
492
486
|
when Error then raise error
|
493
|
-
else raise
|
487
|
+
else raise ParseError.new(error.message, @filename, @line, @column)
|
494
488
|
end
|
495
489
|
end
|
496
490
|
|
data/lib/kdl/v1/kdl.yy
CHANGED
data/lib/kdl/v1/value.rb
CHANGED
@@ -83,7 +83,7 @@ module KDL
|
|
83
83
|
when ::Float then Float.new(value)
|
84
84
|
when TrueClass, FalseClass then Boolean.new(value)
|
85
85
|
when NilClass then Null
|
86
|
-
else raise Error("
|
86
|
+
else raise Error("unsupported value type: #{value.class}")
|
87
87
|
end
|
88
88
|
end
|
89
89
|
end
|
data/lib/kdl/value.rb
CHANGED
@@ -167,7 +167,7 @@ module KDL
|
|
167
167
|
when ::Float then Float.new(value)
|
168
168
|
when TrueClass, FalseClass then Boolean.new(value)
|
169
169
|
when NilClass then Null
|
170
|
-
else raise Error
|
170
|
+
else raise Error, "unsupported value type: #{value.class}"
|
171
171
|
end
|
172
172
|
end
|
173
173
|
end
|
data/lib/kdl/version.rb
CHANGED
data/lib/kdl.rb
CHANGED
@@ -10,6 +10,7 @@ require "kdl/string_dumper"
|
|
10
10
|
require "kdl/types"
|
11
11
|
require "kdl/parser_common"
|
12
12
|
require "kdl/kdl.tab"
|
13
|
+
require "kdl/builder"
|
13
14
|
require "kdl/v1"
|
14
15
|
|
15
16
|
module KDL
|
@@ -23,28 +24,30 @@ module KDL
|
|
23
24
|
parse(input, **options)
|
24
25
|
end
|
25
26
|
|
26
|
-
def self.parse(input, version: default_version, output_version: default_output_version, **options)
|
27
|
+
def self.parse(input, version: default_version, output_version: default_output_version, filename: nil, **options)
|
27
28
|
case version
|
28
29
|
when 2
|
29
|
-
Parser.new(output_module: output_module(output_version || 2), **options).parse(input)
|
30
|
+
Parser.new(output_module: output_module(output_version || 2), **options).parse(input, filename:)
|
30
31
|
when 1
|
31
|
-
V1::Parser.new.parse(input, output_module: output_module(output_version || 1), **options)
|
32
|
+
V1::Parser.new.parse(input, output_module: output_module(output_version || 1), filename:, **options)
|
32
33
|
when nil
|
33
34
|
auto_parse(input, output_version:, **options)
|
34
35
|
else
|
35
|
-
raise UnsupportedVersionError.new("
|
36
|
+
raise UnsupportedVersionError.new("unsupported version '#{version}'", version)
|
36
37
|
end
|
37
38
|
end
|
38
39
|
|
39
40
|
def self.load_file(filespec, **options)
|
40
|
-
|
41
|
+
File.open(filespec, 'r:BOM|UTF-8') do |file|
|
42
|
+
parse(file.read, **options, filename: file.to_path)
|
43
|
+
end
|
41
44
|
end
|
42
45
|
|
43
46
|
def self.auto_parse(input, output_version: default_output_version, **options)
|
44
47
|
parse(input, version: 2, output_version: output_version || 2, **options)
|
45
48
|
rescue VersionMismatchError => e
|
46
49
|
parse(input, version: e.version, output_version: output_version || e.version, **options)
|
47
|
-
rescue
|
50
|
+
rescue ParseError => e
|
48
51
|
parse(input, version: 1, output_version: output_version || 1, **options) rescue raise e
|
49
52
|
end
|
50
53
|
|
@@ -53,8 +56,20 @@ module KDL
|
|
53
56
|
when 1 then KDL::V1
|
54
57
|
when 2 then KDL
|
55
58
|
else
|
56
|
-
warn "Unknown output_version
|
59
|
+
warn "[WARNING] Unknown output_version '#{version}', defaulting to v2"
|
57
60
|
KDL
|
58
61
|
end
|
59
62
|
end
|
63
|
+
|
64
|
+
def self.build(&block)
|
65
|
+
builder = Builder.new
|
66
|
+
if block.arity >= 1
|
67
|
+
builder.document do
|
68
|
+
yield builder
|
69
|
+
end
|
70
|
+
else
|
71
|
+
builder.instance_exec(&block)
|
72
|
+
builder.document
|
73
|
+
end
|
74
|
+
end
|
60
75
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kdl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Danielle Smith
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-
|
10
|
+
date: 2025-09-04 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: racc
|
@@ -87,6 +87,7 @@ files:
|
|
87
87
|
- bin/setup
|
88
88
|
- kdl.gemspec
|
89
89
|
- lib/kdl.rb
|
90
|
+
- lib/kdl/builder.rb
|
90
91
|
- lib/kdl/document.rb
|
91
92
|
- lib/kdl/error.rb
|
92
93
|
- lib/kdl/kdl.tab.rb
|