ruby_grammar_builder 1.1.10 → 1.1.11
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/ruby_grammar_builder/pattern_extensions/or_pattern.rb +54 -0
- data/lib/ruby_grammar_builder/pattern_variations/base_pattern.rb +31 -10
- data/lib/ruby_grammar_builder/pattern_variations/repeatable_pattern.rb +2 -6
- data/lib/ruby_grammar_builder/transforms/resolve_placeholders.rb +12 -75
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 58d3e3e3fe4b1e992aa23abace8ae7ad9d0e7ca6b3e6b1237e1f9f800317fd81
|
4
|
+
data.tar.gz: 2b2423273398cc66d8637d97e41434d7a62c270477b224d5343c339e7f51a33b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 21fb51484f36fcdf93a619ac6e29a96ac2fb50d26dfd3e2a8eb79d2ef7a0c83ec930817045d7340abf9aff5edc9369cb09d2ca4d34fb2c90c280b67527cd817b
|
7
|
+
data.tar.gz: 10c1c631a8bca900ff2c40d9f38ada75cdd310bbcab36cace76f80d745b655f55fbe338fa5d015932a2eef694bbee5434c084e500f0afeb03803b9671b24a0bf
|
@@ -14,7 +14,61 @@ class OrPattern < PatternBase
|
|
14
14
|
def evaluate_operator
|
15
15
|
AlternationOperator.new
|
16
16
|
end
|
17
|
+
|
18
|
+
def run_self_tests
|
19
|
+
pass = [true]
|
17
20
|
|
21
|
+
# some patterns are not able to be evaluated
|
22
|
+
# do not attempt to unless required
|
23
|
+
return true unless [
|
24
|
+
:should_fully_match,
|
25
|
+
:should_not_fully_match,
|
26
|
+
:should_partially_match,
|
27
|
+
:should_not_partially_match,
|
28
|
+
].any? { |k| @arguments.include? k }
|
29
|
+
|
30
|
+
copy = @match.__deep_clone_self__
|
31
|
+
test_regex = copy.to_r
|
32
|
+
test_fully_regex = wrap_with_anchors(copy).to_r
|
33
|
+
|
34
|
+
warn = lambda do |symbol|
|
35
|
+
puts [
|
36
|
+
"",
|
37
|
+
"When testing the pattern #{test_regex.inspect}. The unit test for #{symbol} failed.",
|
38
|
+
"The unit test has the following patterns:",
|
39
|
+
"#{@arguments[symbol].to_yaml}",
|
40
|
+
"The Failing pattern is below:",
|
41
|
+
"#{self}",
|
42
|
+
].join("\n")
|
43
|
+
end
|
44
|
+
if @arguments[:should_fully_match].is_a? Array
|
45
|
+
unless @arguments[:should_fully_match].all? { |test| test =~ test_fully_regex }
|
46
|
+
warn.call :should_fully_match
|
47
|
+
pass << false
|
48
|
+
end
|
49
|
+
end
|
50
|
+
if @arguments[:should_not_fully_match].is_a? Array
|
51
|
+
unless @arguments[:should_not_fully_match].none? { |test| test =~ test_fully_regex }
|
52
|
+
warn.call :should_not_fully_match
|
53
|
+
pass << false
|
54
|
+
end
|
55
|
+
end
|
56
|
+
if @arguments[:should_partially_match].is_a? Array
|
57
|
+
unless @arguments[:should_partially_match].all? { |test| test =~ test_regex }
|
58
|
+
warn.call :should_partially_match
|
59
|
+
pass << false
|
60
|
+
end
|
61
|
+
end
|
62
|
+
if @arguments[:should_not_partially_match].is_a? Array
|
63
|
+
unless @arguments[:should_not_partially_match].none? { |test| test =~ test_regex }
|
64
|
+
warn.call :should_not_partially_match
|
65
|
+
pass << false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
pass.none?(&:!)
|
70
|
+
end
|
71
|
+
|
18
72
|
#
|
19
73
|
# Raises an error to prevent use as initial type
|
20
74
|
#
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
2
|
+
$ruby_grammar_builder__unit_test_active = false
|
3
3
|
#
|
4
4
|
# Provides a base class to simplify the writing of complex regular expressions rules
|
5
5
|
# This class completely handles capture numbers and provides convenience methods for
|
@@ -415,6 +415,8 @@ class PatternBase
|
|
415
415
|
# @return [Boolean] If all test passed return true, otherwise false
|
416
416
|
#
|
417
417
|
def run_tests
|
418
|
+
original_flag_value = $ruby_grammar_builder__unit_test_active
|
419
|
+
$ruby_grammar_builder__unit_test_active = true
|
418
420
|
pass = [
|
419
421
|
run_self_tests,
|
420
422
|
]
|
@@ -427,6 +429,7 @@ class PatternBase
|
|
427
429
|
elsif @arguments[:includes].is_a? PatternBase
|
428
430
|
pass << @arguments[:includes].run_tests
|
429
431
|
end
|
432
|
+
$ruby_grammar_builder__unit_test_active = original_flag_value
|
430
433
|
pass.none?(&:!)
|
431
434
|
end
|
432
435
|
|
@@ -448,8 +451,17 @@ class PatternBase
|
|
448
451
|
].any? { |k| @arguments.include? k }
|
449
452
|
|
450
453
|
copy = __deep_clone_self__
|
451
|
-
|
452
|
-
|
454
|
+
begin
|
455
|
+
test_regex = copy.to_r
|
456
|
+
test_fully_regex = wrap_with_anchors(copy).to_r
|
457
|
+
rescue => exception
|
458
|
+
raise <<~HEREDOC
|
459
|
+
|
460
|
+
|
461
|
+
error running unit tests for: #{copy}
|
462
|
+
#{exception}
|
463
|
+
HEREDOC
|
464
|
+
end
|
453
465
|
|
454
466
|
warn = lambda do |symbol|
|
455
467
|
puts [
|
@@ -719,22 +731,31 @@ class PatternBase
|
|
719
731
|
self_regex = self_regex.gsub(/\(\?\#\[:backreference:([^\\]+?):\]\)/) do
|
720
732
|
match_reference = Regexp.last_match(1)
|
721
733
|
if references[match_reference].nil?
|
722
|
-
|
734
|
+
if $ruby_grammar_builder__unit_test_active
|
735
|
+
"(?#would_be_backref_but_null_because_unit_test)A(?<=B)"
|
736
|
+
else
|
737
|
+
raise "groups:#{groups}\nreferences: #{references}\nWhen processing the matchResultOf:#{match_reference}, I couldn't find the group it was referencing"
|
738
|
+
end
|
739
|
+
else
|
740
|
+
# if the reference does exist, then replace it with it's number
|
741
|
+
"(?:\\#{references[match_reference]})"
|
723
742
|
end
|
724
|
-
|
725
|
-
# if the reference does exist, then replace it with it's number
|
726
|
-
"(?:\\#{references[match_reference]})"
|
727
743
|
end
|
728
744
|
|
729
745
|
# check for a subroutine to the Nth group, replace it with `\N`
|
730
746
|
self_regex = self_regex.gsub(/\(\?\#\[:subroutine:([^\\]+?):\]\)/) do
|
731
747
|
match_reference = Regexp.last_match(1)
|
732
748
|
if references[match_reference].nil?
|
733
|
-
|
749
|
+
if $ruby_grammar_builder__unit_test_active
|
750
|
+
"(?#would_be_subroutine_but_null_because_unit_test)A(?<=B)"
|
751
|
+
else
|
752
|
+
raise "groups:#{groups}\nreferences: #{references}\nWhen processing the recursivelyMatch:#{match_reference}, I couldn't find the group it was referencing"
|
753
|
+
end
|
754
|
+
else
|
755
|
+
# if the reference does exist, then replace it with it's number
|
756
|
+
"\\g<#{references[match_reference]}>"
|
734
757
|
end
|
735
758
|
|
736
|
-
# if the reference does exist, then replace it with it's number
|
737
|
-
"\\g<#{references[match_reference]}>"
|
738
759
|
end
|
739
760
|
# rubocop:enable Metrics/LineLength
|
740
761
|
self_regex
|
@@ -43,10 +43,6 @@ class RepeatablePattern < PatternBase
|
|
43
43
|
# canonize dont_back_track? and as_few_as_possible?
|
44
44
|
@arguments[:dont_back_track?] ||= @arguments[:possessive?]
|
45
45
|
@arguments[:as_few_as_possible?] ||= @arguments[:lazy?]
|
46
|
-
if @arguments[:greedy?]
|
47
|
-
@arguments[:dont_back_track?] = false
|
48
|
-
@arguments[:as_few_as_possible?] = false
|
49
|
-
end
|
50
46
|
# extract the data
|
51
47
|
at_least = attributes_clone[:at_least]
|
52
48
|
at_most = attributes_clone[:at_most]
|
@@ -91,7 +87,7 @@ class RepeatablePattern < PatternBase
|
|
91
87
|
|
92
88
|
# by default assume no quantifiers
|
93
89
|
quantifier = ""
|
94
|
-
# if there is no at_least, at_most, or how_many_times
|
90
|
+
# if there is no at_least, at_most, or how_many_times?, then theres no quantifier
|
95
91
|
if @at_least.nil? and @at_most.nil?
|
96
92
|
quantifier = ""
|
97
93
|
# if there is a quantifier
|
@@ -177,7 +173,7 @@ class RepeatablePattern < PatternBase
|
|
177
173
|
if quantifying_allowed?
|
178
174
|
output += ",\n#{indent} at_least: " + @arguments[:at_least].to_s if @arguments[:at_least]
|
179
175
|
output += ",\n#{indent} at_most: " + @arguments[:at_most].to_s if @arguments[:at_most]
|
180
|
-
output += ",\n#{indent} how_many_times
|
176
|
+
output += ",\n#{indent} how_many_times?: " + @arguments[:how_many_times?].to_s if @arguments[:how_many_times?]
|
181
177
|
output += ",\n#{indent} word_cannot_be_any_of: " + @arguments[:word_cannot_be_any_of].to_s if @arguments[:word_cannot_be_any_of]
|
182
178
|
end
|
183
179
|
output += ",\n#{indent} dont_back_track?: " + @arguments[:dont_back_track?].to_s if @arguments[:dont_back_track?]
|
@@ -5,20 +5,25 @@
|
|
5
5
|
#
|
6
6
|
class ResolvePlaceholders < GrammarTransform
|
7
7
|
def pre_transform(pattern, options)
|
8
|
+
# skip past anything that isn't a pattern
|
8
9
|
return pattern unless pattern.is_a? PatternBase
|
9
10
|
pattern_copy = pattern.__deep_clone__
|
11
|
+
# recursively fill in all of the placeholders by looking them up
|
10
12
|
pattern_copy.map!(true) do |each_pattern_like|
|
11
13
|
|
12
14
|
arguments = each_pattern_like.arguments
|
13
15
|
repository = options[:repository]
|
14
|
-
|
16
|
+
name_of_placeholder = arguments[:placeholder]
|
17
|
+
#
|
18
|
+
# PlaceholderPattern
|
19
|
+
#
|
15
20
|
if each_pattern_like.is_a?(PlaceholderPattern)
|
16
|
-
|
17
|
-
unless repository[
|
18
|
-
raise ":#{
|
21
|
+
# error if can't find thing the placeholder is reffering to
|
22
|
+
unless repository[name_of_placeholder].is_a? PatternBase
|
23
|
+
raise ":#{name_of_placeholder} is not a pattern and cannot be substituted"
|
19
24
|
end
|
20
|
-
|
21
|
-
each_pattern_like.match = repository[
|
25
|
+
# if the pattern exists though, make the substitution
|
26
|
+
each_pattern_like.match = repository[name_of_placeholder].__deep_clone__
|
22
27
|
#
|
23
28
|
# token pattern
|
24
29
|
#
|
@@ -50,72 +55,4 @@ end
|
|
50
55
|
|
51
56
|
# resolving placeholders has no dependencies and makes analyzing patterns much nicer
|
52
57
|
# so it happens fairly early
|
53
|
-
Grammar.register_transform(ResolvePlaceholders.new, 0)
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
# # frozen_string_literal: true
|
60
|
-
|
61
|
-
# #
|
62
|
-
# # Resolves any embedded placeholders
|
63
|
-
# #
|
64
|
-
# class ResolvePlaceholders < GrammarTransform
|
65
|
-
# def pre_transform(pattern, options)
|
66
|
-
# # skip past anything that isn't a pattern
|
67
|
-
# return pattern unless pattern.is_a? PatternBase
|
68
|
-
|
69
|
-
# pattern_copy = pattern.__deep_clone__
|
70
|
-
# # recursively fill in all of the placeholders by looking them up
|
71
|
-
# repository = options[:repository]
|
72
|
-
# pattern_copy.map!(true) do |each_pattern_like|
|
73
|
-
# arguments = each_pattern_like.arguments
|
74
|
-
# name_of_placeholder = arguments[:placeholder]
|
75
|
-
# #
|
76
|
-
# # placeholder pattern
|
77
|
-
# #
|
78
|
-
# if each_pattern_like.is_a?(PlaceholderPattern)
|
79
|
-
# # error if can't find thing the placeholder is reffering to
|
80
|
-
# if !repository[name_of_placeholder].is_a?(PatternBase)
|
81
|
-
# raise "\n#{arguments[:placeholder]} is not a pattern and cannot be substituted"
|
82
|
-
# end
|
83
|
-
|
84
|
-
# # if the pattern exists though, make the substitution
|
85
|
-
# arguments = { match:repository[arguments[:placeholder]].__deep_clone__ }
|
86
|
-
# for each_key, each_value in each_pattern_like.arguments
|
87
|
-
# arguments[each_key] = each_value
|
88
|
-
# end
|
89
|
-
# each_pattern_like = Pattern.new(arguments)
|
90
|
-
# #
|
91
|
-
# # token pattern
|
92
|
-
# #
|
93
|
-
# elsif each_pattern_like.is_a?(TokenPattern)
|
94
|
-
# qualifying_patterns = []
|
95
|
-
# for each_key, each_value in repository
|
96
|
-
# next unless each_value.is_a?(PatternBase)
|
97
|
-
# qualifying_patterns << each_value if arguments[:pattern_filter][each_value]
|
98
|
-
# end
|
99
|
-
# if qualifying_patterns.size == 0
|
100
|
-
# raise <<-HEREDOC.remove_indent
|
101
|
-
|
102
|
-
|
103
|
-
# When creating a token filter #{arguments[:pattern_filter]}
|
104
|
-
# all the patterns that are in the grammar repository were searched
|
105
|
-
# but none of thier adjective lists matched the token filter
|
106
|
-
# HEREDOC
|
107
|
-
# end
|
108
|
-
|
109
|
-
|
110
|
-
# # change this pattern right before the grammar is generated
|
111
|
-
# each_pattern_like.match = oneOf(qualifying_patterns)
|
112
|
-
# end
|
113
|
-
# each_pattern_like
|
114
|
-
# end
|
115
|
-
# return pattern_copy
|
116
|
-
# end
|
117
|
-
# end
|
118
|
-
|
119
|
-
# # resolving placeholders has no dependencies and makes analyzing patterns much nicer
|
120
|
-
# # so it happens fairly early
|
121
|
-
# Grammar.register_transform(ResolvePlaceholders.new, 0)
|
58
|
+
Grammar.register_transform(ResolvePlaceholders.new, 0)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby_grammar_builder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeff Hykin
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-
|
12
|
+
date: 2023-05-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: deep_clone
|