iregexp 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 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