jpt 0.0.1
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 +7 -0
- data/bin/cddlc~ +131 -0
- data/bin/jpc~ +53 -0
- data/bin/jpt +69 -0
- data/bin/jpt~ +53 -0
- data/jpt.gemspec +20 -0
- data/lib/jpt.rb +41 -0
- data/lib/parser/jpt-util.rb +18 -0
- data/lib/parser/jptgrammar.rb +5124 -0
- metadata +110 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: af31eebfdf3961e232c44fce1d5d43ee0c483ce3cf8406fb654a12a874286cba
|
4
|
+
data.tar.gz: 2bd781845060b59cd924edf1f84408f8c47e1c9d8373ae3a21296fce7ad2ee8b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6f4d08616d657cb0f42e9bf90e251ec81792cc4568e3817cf58acb880f23d8558a355e2564383fb0e8d1f91b7d2cefdf5cfb63f3bf28662bc4d6def3e9a9d5ff
|
7
|
+
data.tar.gz: 6e994cde0c251ef44b70959d160ae4c541afc9b2f7ee12d520c0343bc9f95b0ca9058fd6249e9a0b2a9bc5b2b4ccf45cfbe27968ecd4921edc463d1eb061e0b2
|
data/bin/cddlc~
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'pp'
|
3
|
+
require 'yaml'
|
4
|
+
require 'treetop'
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
require_relative '../lib/cddlc.rb'
|
8
|
+
|
9
|
+
def named_keys(tree)
|
10
|
+
# warn [:T, tree].inspect
|
11
|
+
fail unless Array === tree
|
12
|
+
case tree[0]
|
13
|
+
when "seq", "gcho", "tcho"
|
14
|
+
tree[1..-1].flat_map {|x| named_keys(x)}
|
15
|
+
when "rep"
|
16
|
+
named_keys(tree[3])
|
17
|
+
when "mem"
|
18
|
+
key = tree[1]
|
19
|
+
if Array === key && key[0] == "name"
|
20
|
+
[key[1]]
|
21
|
+
end
|
22
|
+
end || []
|
23
|
+
end
|
24
|
+
|
25
|
+
def integer_value(tree)
|
26
|
+
tree and (
|
27
|
+
fail tree.inspect unless Array === tree
|
28
|
+
case tree[0]
|
29
|
+
when "number"
|
30
|
+
tree[1]
|
31
|
+
# XXX: could add other cases
|
32
|
+
end
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
36
|
+
def snaky(name)
|
37
|
+
name.gsub(/-/, "_")
|
38
|
+
end
|
39
|
+
|
40
|
+
Encoding.default_external = Encoding::UTF_8
|
41
|
+
require 'optparse'
|
42
|
+
require 'ostruct'
|
43
|
+
|
44
|
+
$options = OpenStruct.new
|
45
|
+
begin
|
46
|
+
op = OptionParser.new do |opts|
|
47
|
+
opts.banner = "Usage: cddlc.rb [options] file.cddl"
|
48
|
+
|
49
|
+
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
50
|
+
$options.verbose = v
|
51
|
+
end
|
52
|
+
opts.on("-r", "--[no-]rules", "Process rules") do |v|
|
53
|
+
$options.rules = v
|
54
|
+
end
|
55
|
+
opts.on("-x", "--[no-]expand", "Expand generics") do |v|
|
56
|
+
$options.expand_generics = v
|
57
|
+
end
|
58
|
+
opts.on("-u", "--[no-]undefined", "Note undefined names") do |v|
|
59
|
+
$options.note_undefined = v
|
60
|
+
end
|
61
|
+
opts.on("-2", "--[no-]cddl2", "Perform some CDDL 2.0 processing") do |v|
|
62
|
+
$options.cddl2 = v
|
63
|
+
end
|
64
|
+
opts.on("-tFMT", "--to=FMT", [:basic, :neat, :json, :yaml, :enum, :cddl], "Target format") do |v|
|
65
|
+
$options.target = v
|
66
|
+
end
|
67
|
+
end
|
68
|
+
op.parse!
|
69
|
+
rescue Exception => e
|
70
|
+
warn e
|
71
|
+
exit 1
|
72
|
+
end
|
73
|
+
|
74
|
+
if ARGV == []
|
75
|
+
puts op
|
76
|
+
exit 1
|
77
|
+
end
|
78
|
+
cddl_file = ARGF.read
|
79
|
+
|
80
|
+
cddl = CDDL.from_cddl(cddl_file)
|
81
|
+
result = if $options.rules
|
82
|
+
if $options.expand_generics
|
83
|
+
require_relative "../lib/processor/cddl-expander.rb"
|
84
|
+
cddl.expand_generics
|
85
|
+
end
|
86
|
+
cddl.rules
|
87
|
+
else
|
88
|
+
warn "** can't expand in tree; use -r flag as well" if $options.expand_generics
|
89
|
+
cddl.tree
|
90
|
+
end
|
91
|
+
|
92
|
+
warn "** can't note undefined for target != cddl" if $options.note_undefined && $options.target != :cddl
|
93
|
+
|
94
|
+
case $options.target
|
95
|
+
when :basic, nil
|
96
|
+
pp result
|
97
|
+
when :neat, :json
|
98
|
+
require 'neatjson'
|
99
|
+
puts JSON.neat_generate(result, after_comma: 1, after_colon: 1)
|
100
|
+
when :yaml
|
101
|
+
puts result.to_yaml
|
102
|
+
when :enum
|
103
|
+
rules = cddl.rules
|
104
|
+
rules.each do |k, v|
|
105
|
+
if v[0] == "map"
|
106
|
+
nk = v[1..-1].flat_map {|e| named_keys(e)}
|
107
|
+
# warn [:NK, k, nk].inspect
|
108
|
+
nk = nk.map {|name| i = integer_value(rules[name]); [name, i] if i}.compact
|
109
|
+
# warn [:NK, k, nk].inspect
|
110
|
+
if nk != []
|
111
|
+
puts "enum #{snaky(k).downcase}_keys {"
|
112
|
+
nk.each do |n, v|
|
113
|
+
puts " #{snaky(n).upcase} = #{v},"
|
114
|
+
end
|
115
|
+
puts "};"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
when :cddl
|
120
|
+
require_relative '../lib/writer/cddl-writer.rb'
|
121
|
+
if $options.note_undefined
|
122
|
+
require_relative '../lib/processor/cddl-undefined.rb'
|
123
|
+
undef_rule = cddl.cddl_undefined
|
124
|
+
undef_rule.each do |k|
|
125
|
+
puts ";;; *** undefined: #{k}"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
puts cddl.to_s
|
129
|
+
else
|
130
|
+
warn ["Unknown target format: ", $options.target].inspect
|
131
|
+
end
|
data/bin/jpc~
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'pp'
|
3
|
+
require 'yaml'
|
4
|
+
require 'treetop'
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
require_relative '../lib/jpc.rb'
|
8
|
+
|
9
|
+
Encoding.default_external = Encoding::UTF_8
|
10
|
+
require 'optparse'
|
11
|
+
require 'ostruct'
|
12
|
+
|
13
|
+
$options = OpenStruct.new
|
14
|
+
begin
|
15
|
+
op = OptionParser.new do |opts|
|
16
|
+
opts.banner = "Usage: jpc.rb [options] file.jp"
|
17
|
+
|
18
|
+
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
19
|
+
$options.verbose = v
|
20
|
+
end
|
21
|
+
opts.on("-tFMT", "--to=FMT", [:basic, :neat, :json, :yaml, :enum, :jp], "Target format") do |v|
|
22
|
+
$options.target = v
|
23
|
+
end
|
24
|
+
end
|
25
|
+
op.parse!
|
26
|
+
rescue Exception => e
|
27
|
+
warn e
|
28
|
+
exit 1
|
29
|
+
end
|
30
|
+
|
31
|
+
if ARGV == []
|
32
|
+
puts op
|
33
|
+
exit 1
|
34
|
+
end
|
35
|
+
jpc_file = ARGF.read
|
36
|
+
|
37
|
+
jpc = JPC.from_jpc(jpc_file)
|
38
|
+
result = jp.tree
|
39
|
+
|
40
|
+
case $options.target
|
41
|
+
when :basic, nil
|
42
|
+
pp result
|
43
|
+
when :neat, :json
|
44
|
+
require 'neatjson'
|
45
|
+
puts JSON.neat_generate(result, after_comma: 1, after_colon: 1)
|
46
|
+
when :yaml
|
47
|
+
puts result.to_yaml
|
48
|
+
when :jp
|
49
|
+
require_relative '../lib/writer/jp-writer.rb'
|
50
|
+
puts jpc.to_s
|
51
|
+
else
|
52
|
+
warn ["Unknown target format: ", $options.target].inspect
|
53
|
+
end
|
data/bin/jpt
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'pp'
|
3
|
+
require 'yaml'
|
4
|
+
require 'treetop'
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
require_relative '../lib/jpt.rb'
|
8
|
+
|
9
|
+
Encoding.default_external = Encoding::UTF_8
|
10
|
+
require 'optparse'
|
11
|
+
require 'ostruct'
|
12
|
+
|
13
|
+
$options = OpenStruct.new
|
14
|
+
begin
|
15
|
+
op = OptionParser.new do |opts|
|
16
|
+
opts.banner = "Usage: jpt.rb [options] file.jp"
|
17
|
+
|
18
|
+
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
19
|
+
$options.verbose = v
|
20
|
+
end
|
21
|
+
opts.on("-l", "--[no-]lines", "multi-line mode") do |v|
|
22
|
+
$options.lines = v
|
23
|
+
end
|
24
|
+
opts.on("-tFMT", "--to=FMT", [:basic, :neat, :json, :yaml, :enum, :jp], "Target format") do |v|
|
25
|
+
$options.target = v
|
26
|
+
end
|
27
|
+
end
|
28
|
+
op.parse!
|
29
|
+
rescue Exception => e
|
30
|
+
warn e
|
31
|
+
exit 1
|
32
|
+
end
|
33
|
+
|
34
|
+
if ARGV == []
|
35
|
+
puts op
|
36
|
+
exit 1
|
37
|
+
end
|
38
|
+
jp_file = ARGF.read
|
39
|
+
|
40
|
+
if $options.lines
|
41
|
+
lines = jp_file.lines(chomp: true)
|
42
|
+
col = lines.map(&:length).max
|
43
|
+
form = "%-#{col}s %s"
|
44
|
+
lines.each do |line|
|
45
|
+
jpt = JPT.from_jp(line)
|
46
|
+
result = jpt.tree.inspect
|
47
|
+
puts form % [line, result]
|
48
|
+
end
|
49
|
+
else
|
50
|
+
|
51
|
+
jpt = JPT.from_jp(jp_file)
|
52
|
+
result = jpt.tree
|
53
|
+
|
54
|
+
case $options.target
|
55
|
+
when :basic, nil
|
56
|
+
pp result
|
57
|
+
when :neat, :json
|
58
|
+
require 'neatjson'
|
59
|
+
puts JSON.neat_generate(result, after_comma: 1, after_colon: 1)
|
60
|
+
when :yaml
|
61
|
+
puts result.to_yaml
|
62
|
+
when :jp
|
63
|
+
require_relative '../lib/writer/jp-writer.rb'
|
64
|
+
puts jpt.to_s
|
65
|
+
else
|
66
|
+
warn ["Unknown target format: ", $options.target].inspect
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
data/bin/jpt~
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'pp'
|
3
|
+
require 'yaml'
|
4
|
+
require 'treetop'
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
require_relative '../lib/jpt.rb'
|
8
|
+
|
9
|
+
Encoding.default_external = Encoding::UTF_8
|
10
|
+
require 'optparse'
|
11
|
+
require 'ostruct'
|
12
|
+
|
13
|
+
$options = OpenStruct.new
|
14
|
+
begin
|
15
|
+
op = OptionParser.new do |opts|
|
16
|
+
opts.banner = "Usage: jpt.rb [options] file.jp"
|
17
|
+
|
18
|
+
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
19
|
+
$options.verbose = v
|
20
|
+
end
|
21
|
+
opts.on("-tFMT", "--to=FMT", [:basic, :neat, :json, :yaml, :enum, :jp], "Target format") do |v|
|
22
|
+
$options.target = v
|
23
|
+
end
|
24
|
+
end
|
25
|
+
op.parse!
|
26
|
+
rescue Exception => e
|
27
|
+
warn e
|
28
|
+
exit 1
|
29
|
+
end
|
30
|
+
|
31
|
+
if ARGV == []
|
32
|
+
puts op
|
33
|
+
exit 1
|
34
|
+
end
|
35
|
+
jp_file = ARGF.read
|
36
|
+
|
37
|
+
jpt = JPT.from_jp(jp_file)
|
38
|
+
result = jpt.tree
|
39
|
+
|
40
|
+
case $options.target
|
41
|
+
when :basic, nil
|
42
|
+
pp result
|
43
|
+
when :neat, :json
|
44
|
+
require 'neatjson'
|
45
|
+
puts JSON.neat_generate(result, after_comma: 1, after_colon: 1)
|
46
|
+
when :yaml
|
47
|
+
puts result.to_yaml
|
48
|
+
when :jp
|
49
|
+
require_relative '../lib/writer/jp-writer.rb'
|
50
|
+
puts jpt.to_s
|
51
|
+
else
|
52
|
+
warn ["Unknown target format: ", $options.target].inspect
|
53
|
+
end
|
data/jpt.gemspec
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "jpt"
|
3
|
+
s.version = "0.0.1"
|
4
|
+
s.summary = "JSONPath tools"
|
5
|
+
s.description = %q{jpt implements converters and miscellaneous tools for JSONPath}
|
6
|
+
s.author = "Carsten Bormann"
|
7
|
+
s.email = "cabo@tzi.org"
|
8
|
+
s.license = "MIT"
|
9
|
+
s.homepage = "http://github.com/cabo/jpt"
|
10
|
+
s.files = Dir['lib/**/*.rb'] + %w(jpt.gemspec) + Dir['data/*'] + Dir['bin/**/*.rb']
|
11
|
+
s.executables = Dir['bin/*'].map {|x| File.basename(x)}
|
12
|
+
s.required_ruby_version = '>= 3.0'
|
13
|
+
|
14
|
+
s.require_paths = ["lib"]
|
15
|
+
|
16
|
+
s.add_development_dependency 'bundler', '~>1'
|
17
|
+
s.add_dependency 'treetop', '~>1'
|
18
|
+
s.add_dependency 'json'
|
19
|
+
s.add_dependency 'neatjson'
|
20
|
+
end
|
data/lib/jpt.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require_relative "parser/jpt-util.rb"
|
2
|
+
|
3
|
+
class JPT
|
4
|
+
@@parser = JPTGRAMMARParser.new
|
5
|
+
|
6
|
+
DATA_DIR = Pathname.new(__FILE__) + "../../data/"
|
7
|
+
|
8
|
+
def self.reason(parser, s)
|
9
|
+
reason = [parser.failure_reason]
|
10
|
+
parser.failure_reason =~ /^(Expected .+) after/m
|
11
|
+
reason << "#{$1.gsub("\n", '<<<NEWLINE>>>')}:" if $1
|
12
|
+
if line = s.lines.to_a[parser.failure_line - 1]
|
13
|
+
reason << line
|
14
|
+
reason << "#{'~' * (parser.failure_column - 1)}^"
|
15
|
+
end
|
16
|
+
reason.join("\n")
|
17
|
+
end
|
18
|
+
|
19
|
+
SAFE_FN = /\A[-._a-zA-Z0-9]+\z/
|
20
|
+
|
21
|
+
def self.from_jp(s)
|
22
|
+
ast = @@parser.parse s
|
23
|
+
if !ast
|
24
|
+
fail self.reason(@@parser, s)
|
25
|
+
end
|
26
|
+
ret = JPT.new(ast)
|
27
|
+
|
28
|
+
ret
|
29
|
+
end
|
30
|
+
|
31
|
+
attr_accessor :ast, :tree, :directives
|
32
|
+
def initialize(ast_)
|
33
|
+
@ast = ast_
|
34
|
+
@tree = ast.ast
|
35
|
+
end
|
36
|
+
|
37
|
+
def deep_clone
|
38
|
+
Marshal.load(Marshal.dump(self))
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'treetop'
|
2
|
+
require_relative './jptgrammar'
|
3
|
+
|
4
|
+
class Treetop::Runtime::SyntaxNode
|
5
|
+
def ast
|
6
|
+
fail "undefined_ast #{inspect}"
|
7
|
+
end
|
8
|
+
def ast1 # devhack
|
9
|
+
"#{inspect[10..20]}--#{text_value[0..15]}"
|
10
|
+
end
|
11
|
+
def repwrap(el, val)
|
12
|
+
if el.text_value == ''
|
13
|
+
val
|
14
|
+
else
|
15
|
+
["rep", *el.ast, val]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|