iregexp 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/iregexp +119 -0
- data/bin/iregexp~ +102 -0
- data/iregexp.gemspec +21 -0
- data/lib/iregexp.rb +39 -0
- data/lib/parser/iregexp-util.rb +12 -0
- data/lib/parser/iregexpgrammar.rb +1978 -0
- data/lib/writer/iregexp-writer.rb +92 -0
- metadata +107 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e6fe6ee35f1dd62cd10b9aa7105cf58c46f76c16f20a23a752c70ffd3e043fb6
|
4
|
+
data.tar.gz: 93a7a857b277c22f055b922761cdd152524fd48c8755ca503501f5082bf78263
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c8dc4f7369ab2e828fb3be27f848369a7763a4345f0aec9026a11b4397a3ef2b3bfc34648bcf18013435be8fac05582203b965f5bbd9ead54cbcc10d48774354
|
7
|
+
data.tar.gz: 1d43505cf373b29f6cf8e670b644e879e10b0dba00a4efc06c56610026be8fb3c796fd96f1ca9247ef170682b92f0b8d223f96367bc78c86453eef153c621a11
|
data/bin/iregexp
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'pp'
|
3
|
+
require 'yaml'
|
4
|
+
require 'treetop'
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
require_relative '../lib/iregexp'
|
8
|
+
|
9
|
+
Encoding.default_external = Encoding::UTF_8
|
10
|
+
require 'optparse'
|
11
|
+
require 'ostruct'
|
12
|
+
|
13
|
+
FUNCSIG_CHARS = {"l" => :logical, "n" => :nodes, "v" => :value}
|
14
|
+
|
15
|
+
$options = OpenStruct.new
|
16
|
+
begin
|
17
|
+
op = OptionParser.new do |opts|
|
18
|
+
opts.banner = "Usage: jpt.rb [options] file.jp"
|
19
|
+
|
20
|
+
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
21
|
+
$options.verbose = v
|
22
|
+
end
|
23
|
+
opts.on("-l", "--[no-]lines", "multi-line mode") do |v|
|
24
|
+
$options.lines = v
|
25
|
+
end
|
26
|
+
opts.on("-eREGEXP", "--e=REGEXP", "supply iregexp on command line") do |v|
|
27
|
+
$options.regexp = v
|
28
|
+
end
|
29
|
+
opts.on("-tFMT", "--to=FMT", [:basic, :neat, :json, :yaml, :iregexp, :ire, :pcre, :js, :example, :random], "Target format") do |v|
|
30
|
+
$options.target = v
|
31
|
+
end
|
32
|
+
end
|
33
|
+
op.parse!
|
34
|
+
rescue Exception => e
|
35
|
+
warn e
|
36
|
+
exit 1
|
37
|
+
end
|
38
|
+
|
39
|
+
if !$options.regexp
|
40
|
+
if ARGV == []
|
41
|
+
puts op
|
42
|
+
exit 1
|
43
|
+
end
|
44
|
+
$options.regexp = ARGF.read
|
45
|
+
else
|
46
|
+
if ARGV != []
|
47
|
+
warn "*** file names #{ARGV.join(", ")} ignored due to -e given"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
input_file = $options.regexp
|
52
|
+
|
53
|
+
if $options.lines
|
54
|
+
require_relative '../lib/writer/iregexp-writer.rb'
|
55
|
+
require "regexp-examples"
|
56
|
+
|
57
|
+
lines = input_file.lines(chomp: true)
|
58
|
+
col = lines.map(&:length).max
|
59
|
+
form = "%-#{col}s %s"
|
60
|
+
lines.each do |line|
|
61
|
+
re = line[1..-1]
|
62
|
+
next unless re
|
63
|
+
ok = line[0] =~ /\A[=*]\z/ # * = error in example generator
|
64
|
+
begin
|
65
|
+
ire = IREGEXP.from_iregexp(re)
|
66
|
+
result = ire.tree.inspect
|
67
|
+
puts form % [line, result]
|
68
|
+
fail "is marked as failing, but seems to be ok" unless ok
|
69
|
+
if line[0] == "*"
|
70
|
+
puts form % ["", "bug in regexp example generator:"]
|
71
|
+
end
|
72
|
+
puts form % ["", ire.to_regexp.
|
73
|
+
examples(max_repeater_variance: 4, max_group_results: 20).
|
74
|
+
map{ |s| JSON.dump(s)}.
|
75
|
+
join(", ")]
|
76
|
+
rescue IREGEXP::ParseError => e
|
77
|
+
l = line
|
78
|
+
e.to_s.lines.each do |li|
|
79
|
+
puts form % [l, li]
|
80
|
+
l = ""
|
81
|
+
end
|
82
|
+
fail "is marked as ok, but seems to be failing" if ok
|
83
|
+
end
|
84
|
+
end
|
85
|
+
else
|
86
|
+
|
87
|
+
ire = IREGEXP.from_iregexp(input_file)
|
88
|
+
result = ire.tree
|
89
|
+
|
90
|
+
case $options.target
|
91
|
+
when :basic, nil
|
92
|
+
pp result
|
93
|
+
when :neat, :json
|
94
|
+
require 'neatjson'
|
95
|
+
puts JSON.neat_generate(result, after_comma: 1, after_colon: 1)
|
96
|
+
when :yaml
|
97
|
+
puts result.to_yaml
|
98
|
+
when :iregexp, :ire
|
99
|
+
require_relative '../lib/writer/iregexp-writer.rb'
|
100
|
+
puts ire.to_s
|
101
|
+
when :pcre
|
102
|
+
require_relative '../lib/writer/iregexp-writer.rb'
|
103
|
+
puts ire.to_pcre
|
104
|
+
when :js
|
105
|
+
require_relative '../lib/writer/iregexp-writer.rb'
|
106
|
+
puts ire.to_js
|
107
|
+
when :example
|
108
|
+
require_relative '../lib/writer/iregexp-writer.rb'
|
109
|
+
require "regexp-examples"
|
110
|
+
puts ire.to_regexp.examples(max_repeater_variance: 4, max_group_results: 20)
|
111
|
+
when :random
|
112
|
+
require_relative '../lib/writer/iregexp-writer.rb'
|
113
|
+
require "regexp-examples"
|
114
|
+
puts ire.to_regexp.random_example(max_repeater_variance: 4)
|
115
|
+
else
|
116
|
+
warn ["Unknown target format: ", $options.target].inspect
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
data/bin/iregexp~
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'pp'
|
3
|
+
require 'yaml'
|
4
|
+
require 'treetop'
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
require_relative '../lib/jpt'
|
8
|
+
|
9
|
+
Encoding.default_external = Encoding::UTF_8
|
10
|
+
require 'optparse'
|
11
|
+
require 'ostruct'
|
12
|
+
|
13
|
+
FUNCSIG_CHARS = {"l" => :logical, "n" => :nodes, "v" => :value}
|
14
|
+
|
15
|
+
$options = OpenStruct.new
|
16
|
+
begin
|
17
|
+
op = OptionParser.new do |opts|
|
18
|
+
opts.banner = "Usage: jpt.rb [options] file.jp"
|
19
|
+
|
20
|
+
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
21
|
+
$options.verbose = v
|
22
|
+
end
|
23
|
+
opts.on("-l", "--[no-]lines", "multi-line mode") do |v|
|
24
|
+
$options.lines = v
|
25
|
+
end
|
26
|
+
opts.on("-q", "--[no-]test", "test-file mode") do |v|
|
27
|
+
$options.test = v
|
28
|
+
end
|
29
|
+
opts.on("-fFUNCSIG", "--[no-]f=FUNCSIG", "add function signature name=rppp") do |v|
|
30
|
+
fail "funcsig format must be name=rppp" unless v =~ /\A([a-z][_a-z0-9]*)-([lnv]+)\z/
|
31
|
+
|
32
|
+
JPTType.add_funcsig($1, $2)
|
33
|
+
end
|
34
|
+
opts.on("-tFMT", "--to=FMT", [:basic, :neat, :json, :yaml, :enum, :jp], "Target format") do |v|
|
35
|
+
$options.target = v
|
36
|
+
end
|
37
|
+
end
|
38
|
+
op.parse!
|
39
|
+
rescue Exception => e
|
40
|
+
warn e
|
41
|
+
exit 1
|
42
|
+
end
|
43
|
+
|
44
|
+
if ARGV == []
|
45
|
+
puts op
|
46
|
+
exit 1
|
47
|
+
end
|
48
|
+
jp_file = ARGF.read
|
49
|
+
|
50
|
+
if $options.test
|
51
|
+
argument = query = output = nil
|
52
|
+
jp_file.scan(/((?:^(?:$|[^$=].*)\n)+)|([$].*)|=(.*)|#.*/) do |arg,qy,out|
|
53
|
+
begin
|
54
|
+
if arg
|
55
|
+
argument = JSON.parse(arg)
|
56
|
+
puts
|
57
|
+
puts JSON.dump(argument)
|
58
|
+
elsif qy
|
59
|
+
jpt = JPT.from_jp(qy)
|
60
|
+
output = jpt.apply(argument)
|
61
|
+
print jpt.tree.inspect << " "
|
62
|
+
puts "➔ #{JSON.dump(output)}"
|
63
|
+
elsif out
|
64
|
+
suggested = JSON.parse(out)
|
65
|
+
if output != suggested
|
66
|
+
p [:SUGGESTED, suggested]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
rescue => e
|
70
|
+
warn "*** #{e.detailed_message} #{e.backtrace}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
elsif $options.lines
|
74
|
+
lines = jp_file.lines(chomp: true)
|
75
|
+
col = lines.map(&:length).max
|
76
|
+
form = "%-#{col}s %s"
|
77
|
+
lines.each do |line|
|
78
|
+
jpt = JPT.from_jp(line)
|
79
|
+
result = jpt.tree.inspect
|
80
|
+
puts form % [line, result]
|
81
|
+
end
|
82
|
+
else
|
83
|
+
|
84
|
+
jpt = JPT.from_jp(jp_file)
|
85
|
+
result = jpt.tree
|
86
|
+
|
87
|
+
case $options.target
|
88
|
+
when :basic, nil
|
89
|
+
pp result
|
90
|
+
when :neat, :json
|
91
|
+
require 'neatjson'
|
92
|
+
puts JSON.neat_generate(result, after_comma: 1, after_colon: 1)
|
93
|
+
when :yaml
|
94
|
+
puts result.to_yaml
|
95
|
+
when :jp
|
96
|
+
require_relative '../lib/writer/jp-writer.rb'
|
97
|
+
puts jpt.to_s
|
98
|
+
else
|
99
|
+
warn ["Unknown target format: ", $options.target].inspect
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
data/iregexp.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "iregexp"
|
3
|
+
s.version = "0.0.1"
|
4
|
+
s.summary = "I-Regexp Tools"
|
5
|
+
s.description = %q{iregexp implements converters and miscellaneous tools for I-Regexp}
|
6
|
+
s.author = "Carsten Bormann"
|
7
|
+
s.email = "cabo@tzi.org"
|
8
|
+
s.license = "MIT"
|
9
|
+
s.homepage = "http://github.com/cabo/iregexp"
|
10
|
+
s.files = Dir['lib/**/*.rb'] + %w(iregexp.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', '~>0.10'
|
20
|
+
s.add_dependency 'regexp-examples', '~>1.5.1'
|
21
|
+
end
|
data/lib/iregexp.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require_relative "parser/iregexp-util.rb"
|
2
|
+
|
3
|
+
class IREGEXP
|
4
|
+
@@parser = IREGEXPGRAMMARParser.new
|
5
|
+
# include ::IREGEXPType
|
6
|
+
|
7
|
+
class ParseError < ArgumentError; end
|
8
|
+
|
9
|
+
DATA_DIR = Pathname.new(__FILE__) + "../../data/"
|
10
|
+
|
11
|
+
def self.reason(parser, s)
|
12
|
+
reason = [parser.failure_reason]
|
13
|
+
parser.failure_reason =~ /^(Expected .+) after/m
|
14
|
+
reason = ["#{$1.gsub("\n", '<<<NEWLINE>>>')}:"] if $1
|
15
|
+
if line = s.lines.to_a[parser.failure_line - 1]
|
16
|
+
reason << line
|
17
|
+
reason << "#{'~' * (parser.failure_column - 1)}^"
|
18
|
+
end
|
19
|
+
reason.join("\n").gsub(/[\u0000-\u0009\u000b\u001f\u007f]/) {|c| "\\u%04x" % c.ord}
|
20
|
+
end
|
21
|
+
|
22
|
+
SAFE_FN = /\A[-._a-zA-Z0-9]+\z/
|
23
|
+
|
24
|
+
def self.from_iregexp(s)
|
25
|
+
ast = @@parser.parse s
|
26
|
+
if !ast
|
27
|
+
fail ParseError.new(self.reason(@@parser, s))
|
28
|
+
end
|
29
|
+
ret = IREGEXP.new(ast)
|
30
|
+
|
31
|
+
ret
|
32
|
+
end
|
33
|
+
|
34
|
+
attr_accessor :ast, :tree, :directives
|
35
|
+
def initialize(ast_)
|
36
|
+
@ast = ast_
|
37
|
+
@tree = ast.ast
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'treetop'
|
2
|
+
require_relative './iregexpgrammar'
|
3
|
+
require_relative '../iregexp'
|
4
|
+
|
5
|
+
class Treetop::Runtime::SyntaxNode
|
6
|
+
def ast
|
7
|
+
fail "undefined_ast #{inspect}"
|
8
|
+
end
|
9
|
+
def ast1 # devhack
|
10
|
+
"#{inspect[10..20]}--#{text_value[0..15]}"
|
11
|
+
end
|
12
|
+
end
|