iregexp 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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