srl_ruby 0.4.5 → 0.4.9
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 +5 -5
- data/.rubocop.yml +298 -23
- data/CHANGELOG.md +41 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +1 -1
- data/README.md +1 -1
- data/Rakefile +3 -0
- data/appveyor.yml +14 -12
- data/bin/srl2ruby +13 -9
- data/bin/srl2ruby_cli_parser.rb +3 -3
- data/features/lib/step_definitions/srl_testing_steps.rb +2 -0
- data/features/lib/support/env..rb +2 -0
- data/lib/regex/abstract_method.rb +2 -0
- data/lib/regex/alternation.rb +3 -3
- data/lib/regex/anchor.rb +3 -0
- data/lib/regex/atomic_expression.rb +2 -0
- data/lib/regex/capturing_group.rb +8 -3
- data/lib/regex/char_class.rb +4 -2
- data/lib/regex/char_range.rb +3 -3
- data/lib/regex/char_shorthand.rb +3 -0
- data/lib/regex/character.rb +5 -2
- data/lib/regex/compound_expression.rb +2 -0
- data/lib/regex/concatenation.rb +3 -1
- data/lib/regex/expression.rb +6 -1
- data/lib/regex/lookaround.rb +3 -1
- data/lib/regex/match_option.rb +2 -0
- data/lib/regex/monadic_expression.rb +2 -0
- data/lib/regex/multiplicity.rb +8 -9
- data/lib/regex/non_capturing_group.rb +3 -1
- data/lib/regex/polyadic_expression.rb +2 -0
- data/lib/regex/quantifiable.rb +3 -1
- data/lib/regex/raw_expression.rb +2 -0
- data/lib/regex/repetition.rb +2 -0
- data/lib/regex/wildcard.rb +2 -5
- data/lib/srl_ruby/ast_builder.rb +81 -121
- data/lib/srl_ruby/grammar.rb +80 -92
- data/lib/srl_ruby/regex_repr.rb +2 -0
- data/lib/srl_ruby/tokenizer.rb +10 -4
- data/lib/srl_ruby/version.rb +3 -1
- data/lib/srl_ruby.rb +2 -0
- data/spec/acceptance/srl_test_suite_spec.rb +2 -0
- data/spec/acceptance/support/rule_file_ast_builder.rb +2 -0
- data/spec/acceptance/support/rule_file_grammar.rb +7 -5
- data/spec/acceptance/support/rule_file_nodes.rb +2 -0
- data/spec/acceptance/support/rule_file_parser.rb +2 -0
- data/spec/acceptance/support/rule_file_tokenizer.rb +10 -3
- data/spec/regex/atomic_expression_spec.rb +2 -0
- data/spec/regex/character_spec.rb +16 -6
- data/spec/regex/match_option_spec.rb +2 -0
- data/spec/regex/monadic_expression_spec.rb +2 -0
- data/spec/regex/multiplicity_spec.rb +4 -0
- data/spec/regex/repetition_spec.rb +2 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/srl_ruby/srl_ruby_spec.rb +2 -0
- data/spec/srl_ruby/tokenizer_spec.rb +2 -0
- data/spec/srl_ruby_spec.rb +8 -6
- data/srl_ruby.gemspec +6 -4
- metadata +13 -14
data/lib/srl_ruby/grammar.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Grammar for SRL (Simple Regex Language)
|
2
4
|
require 'rley' # Load the gem
|
3
5
|
module SrlRuby
|
4
6
|
########################################
|
5
7
|
# SRL grammar
|
6
|
-
builder = Rley::
|
8
|
+
builder = Rley::grammar_builder do
|
7
9
|
# Separators...
|
8
10
|
add_terminals('LPAREN', 'RPAREN', 'COMMA')
|
9
11
|
|
@@ -29,97 +31,83 @@ module SrlRuby
|
|
29
31
|
add_terminals('LAZY')
|
30
32
|
|
31
33
|
# Grammar rules...
|
32
|
-
rule('srl' => 'expression').
|
33
|
-
rule('expression' =>
|
34
|
-
rule('
|
35
|
-
rule('
|
36
|
-
rule('
|
37
|
-
rule('
|
38
|
-
rule('
|
39
|
-
rule('
|
40
|
-
rule('
|
41
|
-
rule('
|
42
|
-
rule('
|
43
|
-
rule('
|
44
|
-
rule('
|
45
|
-
rule('
|
46
|
-
rule('
|
47
|
-
rule('
|
48
|
-
rule('
|
49
|
-
rule('
|
50
|
-
rule('
|
51
|
-
rule('
|
52
|
-
rule('
|
53
|
-
rule('
|
54
|
-
rule('
|
55
|
-
rule('
|
56
|
-
rule('
|
57
|
-
rule('
|
58
|
-
rule('
|
59
|
-
rule('
|
60
|
-
rule('
|
61
|
-
rule('
|
62
|
-
rule('
|
63
|
-
rule('
|
64
|
-
rule('
|
65
|
-
rule('
|
66
|
-
rule('
|
67
|
-
rule('
|
68
|
-
rule('
|
69
|
-
rule('
|
70
|
-
rule('
|
71
|
-
rule('
|
72
|
-
rule('
|
73
|
-
rule('
|
74
|
-
rule('
|
75
|
-
rule('
|
76
|
-
rule('
|
77
|
-
rule('
|
78
|
-
rule('
|
79
|
-
rule('
|
80
|
-
rule('
|
81
|
-
rule('
|
82
|
-
rule('
|
83
|
-
rule('
|
84
|
-
rule('
|
85
|
-
rule('
|
86
|
-
rule('
|
87
|
-
rule('
|
88
|
-
rule('
|
89
|
-
rule('
|
90
|
-
rule('
|
91
|
-
rule('
|
92
|
-
rule('
|
93
|
-
rule('
|
94
|
-
rule('
|
95
|
-
rule('
|
96
|
-
rule('
|
97
|
-
rule('
|
98
|
-
rule('
|
99
|
-
rule('
|
100
|
-
rule('
|
101
|
-
rule('
|
102
|
-
rule('
|
103
|
-
rule('
|
104
|
-
rule('
|
105
|
-
rule('
|
106
|
-
rule('
|
107
|
-
rule('
|
108
|
-
rule('
|
109
|
-
rule('quantifier' => 'ONCE').as 'once'
|
110
|
-
rule('quantifier' => 'TWICE').as 'twice'
|
111
|
-
rule('quantifier' => %w[EXACTLY count TIMES]).as 'exactly'
|
112
|
-
rule('quantifier' => %w[BETWEEN count AND count times_suffix]).as 'between_and'
|
113
|
-
rule('quantifier' => 'OPTIONAL').as 'optional'
|
114
|
-
rule('quantifier' => %w[ONCE OR MORE]).as 'once_or_more'
|
115
|
-
rule('quantifier' => %w[NEVER OR MORE]).as 'never_or_more'
|
116
|
-
rule('quantifier' => %w[AT LEAST count TIMES]).as 'at_least'
|
117
|
-
rule('digit_or_number' => 'DIGIT').as 'digit_keyword'
|
118
|
-
rule('digit_or_number' => 'NUMBER').as 'number_keyword'
|
119
|
-
rule('count' => 'DIGIT_LIT').as 'single_digit'
|
120
|
-
rule('count' => 'INTEGER').as 'integer_count'
|
121
|
-
rule('times_suffix' => 'TIMES').as 'times_keyword'
|
122
|
-
rule('times_suffix' => []).as 'times_dropped'
|
34
|
+
rule('srl' => 'expression').tag 'start_rule'
|
35
|
+
rule('expression' => 'pattern flags?').tag 'flagged_expr'
|
36
|
+
rule('pattern' => 'sub_pattern (separator sub_pattern)*').tag 'pattern_sequence'
|
37
|
+
rule('sub_pattern' => 'quantifiable').tag 'quantifiable_sub_pattern'
|
38
|
+
rule('sub_pattern' => 'assertion').tag 'assertion_sub_pattern'
|
39
|
+
rule('separator' => 'COMMA?')
|
40
|
+
rule('flags' => '(separator single_flag)+').tag 'flag_sequence'
|
41
|
+
rule('single_flag' => 'CASE INSENSITIVE').tag 'case_insensitive'
|
42
|
+
rule('single_flag' => 'MULTI LINE').tag 'multi_line'
|
43
|
+
rule('single_flag' => 'ALL LAZY').tag 'all_lazy'
|
44
|
+
rule('quantifiable' => 'begin_anchor? anchorable end_anchor?').tag 'quantifiable'
|
45
|
+
rule('begin_anchor' => 'STARTS WITH').tag 'starts_with'
|
46
|
+
rule('begin_anchor' => 'BEGIN WITH').tag 'begin_with'
|
47
|
+
rule('end_anchor' => 'separator MUST END').tag 'end_anchor'
|
48
|
+
rule('anchorable' => 'assertable').tag 'simple_anchorable'
|
49
|
+
rule('assertion' => 'IF NOT? FOLLOWED BY assertable').tag 'if_followed'
|
50
|
+
rule('assertion' => 'IF NOT? ALREADY HAD assertable').tag 'if_had'
|
51
|
+
rule('assertable' => 'term quantifier?').tag 'assertable'
|
52
|
+
rule('term' => 'atom').tag 'atom_term'
|
53
|
+
rule('term' => 'alternation').tag 'alternation_term'
|
54
|
+
rule('term' => 'grouping').tag 'grouping_term'
|
55
|
+
rule('term' => 'capturing_group').tag 'capturing_group_atom'
|
56
|
+
rule('atom' => 'letter_range').tag 'letter_range_atom'
|
57
|
+
rule('atom' => 'digit_range').tag 'digit_range_atom'
|
58
|
+
rule('atom' => 'character_class').tag 'character_class_atom'
|
59
|
+
rule('atom' => 'special_char').tag 'special_char_atom'
|
60
|
+
rule('atom' => 'literal').tag 'literal_atom'
|
61
|
+
rule('atom' => 'raw').tag 'raw_atom'
|
62
|
+
rule('letter_range' => 'LETTER FROM LETTER_LIT TO LETTER_LIT').tag 'lowercase_from_to'
|
63
|
+
rule('letter_range' => 'UPPERCASE LETTER FROM LETTER_LIT TO LETTER_LIT').tag 'uppercase_from_to'
|
64
|
+
rule('letter_range' => 'LETTER').tag 'any_lowercase'
|
65
|
+
rule('letter_range' => 'UPPERCASE LETTER').tag 'any_uppercase'
|
66
|
+
rule('digit_range' => 'digit_or_number FROM DIGIT_LIT TO DIGIT_LIT').tag 'digits_from_to'
|
67
|
+
rule('character_class' => 'ANY CHARACTER').tag 'any_character'
|
68
|
+
rule('character_class' => 'NO CHARACTER').tag 'no_character'
|
69
|
+
rule('character_class' => 'digit_or_number').tag 'digit'
|
70
|
+
rule('character_class' => 'NO DIGIT').tag 'non_digit'
|
71
|
+
rule('character_class' => 'WHITESPACE').tag 'whitespace'
|
72
|
+
rule('character_class' => 'NO WHITESPACE').tag 'no_whitespace'
|
73
|
+
rule('character_class' => 'ANYTHING').tag 'anything'
|
74
|
+
rule('character_class' => 'ONE OF cclass').tag 'one_of'
|
75
|
+
rule('character_class' => 'NONE OF cclass').tag 'none_of'
|
76
|
+
rule('cclass' => 'STRING_LIT').tag 'quoted_cclass' # Preferred syntax
|
77
|
+
rule('cclass' => 'INTEGER').tag 'digits_cclass'
|
78
|
+
rule('cclass' => 'IDENTIFIER').tag 'identifier_cclass'
|
79
|
+
rule('cclass' => 'CHAR_CLASS').tag 'unquoted_cclass'
|
80
|
+
rule('special_char' => 'TAB').tag 'tab'
|
81
|
+
rule('special_char' => 'VERTICAL TAB').tag 'vtab'
|
82
|
+
rule('special_char' => 'BACKSLASH').tag 'backslash'
|
83
|
+
rule('special_char' => 'NEW LINE').tag 'new_line'
|
84
|
+
rule('special_char' => 'CARRIAGE RETURN').tag 'carriage_return'
|
85
|
+
rule('special_char' => 'WORD').tag 'word'
|
86
|
+
rule('special_char' => 'NO WORD').tag 'no_word'
|
87
|
+
rule('literal' => 'LITERALLY STRING_LIT').tag 'literally'
|
88
|
+
rule('raw' => 'RAW STRING_LIT').tag 'raw_literal'
|
89
|
+
rule('alternation' => 'any_or_either OF LPAREN alternatives RPAREN').tag 'any_of'
|
90
|
+
rule('alternatives' => 'alternatives separator quantifiable').tag 'alternative_list'
|
91
|
+
rule('alternatives' => 'quantifiable').tag 'simple_alternative'
|
92
|
+
rule('any_or_either' => 'ANY').tag 'any_keyword'
|
93
|
+
rule('any_or_either' => 'EITHER').tag 'either_keyword'
|
94
|
+
rule('grouping' => 'LPAREN pattern RPAREN').tag 'grouping_parenthenses'
|
95
|
+
rule('capturing_group' => 'CAPTURE assertable (UNTIL assertable)?').tag 'capture'
|
96
|
+
rule('capturing_group' => 'CAPTURE assertable AS var_name (UNTIL assertable)?').tag 'named_capture'
|
97
|
+
rule('var_name' => 'STRING_LIT').tag 'var_name'
|
98
|
+
rule('var_name' => 'IDENTIFIER').tag 'var_ident' # capture name not enclosed between quotes
|
99
|
+
rule('quantifier' => 'ONCE').tag 'once'
|
100
|
+
rule('quantifier' => 'TWICE').tag 'twice'
|
101
|
+
rule('quantifier' => 'EXACTLY count TIMES').tag 'exactly'
|
102
|
+
rule('quantifier' => 'BETWEEN count AND count TIMES?').tag 'between_and'
|
103
|
+
rule('quantifier' => 'OPTIONAL').tag 'optional'
|
104
|
+
rule('quantifier' => 'ONCE OR MORE').tag 'once_or_more'
|
105
|
+
rule('quantifier' => 'NEVER OR MORE').tag 'never_or_more'
|
106
|
+
rule('quantifier' => 'AT LEAST count TIMES').tag 'at_least'
|
107
|
+
rule('digit_or_number' => 'DIGIT').tag 'digit_keyword'
|
108
|
+
rule('digit_or_number' => 'NUMBER').tag 'number_keyword'
|
109
|
+
rule('count' => 'DIGIT_LIT').tag 'single_digit'
|
110
|
+
rule('count' => 'INTEGER').tag 'integer_count'
|
123
111
|
end
|
124
112
|
|
125
113
|
# And now build the grammar and make it accessible via a global constant
|
data/lib/srl_ruby/regex_repr.rb
CHANGED
data/lib/srl_ruby/tokenizer.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# File: srl_tokenizer.rb
|
2
4
|
# Tokenizer for SRL (Simple Regex Language)
|
3
5
|
require 'strscan'
|
@@ -15,10 +17,14 @@ module SrlRuby
|
|
15
17
|
# Delimiters: parentheses '(' and ')'
|
16
18
|
# Separators: comma (optional)
|
17
19
|
class Tokenizer
|
20
|
+
# @return [StringScanner]
|
18
21
|
attr_reader(:scanner)
|
22
|
+
|
23
|
+
# @return [Integer] current line number
|
19
24
|
attr_reader(:lineno)
|
25
|
+
|
26
|
+
# @return [Integer] offset of start of current line within input
|
20
27
|
attr_reader(:line_start)
|
21
|
-
# attr_reader(:column)
|
22
28
|
|
23
29
|
@@lexeme2name = {
|
24
30
|
'(' => 'LPAREN',
|
@@ -84,7 +90,7 @@ module SrlRuby
|
|
84
90
|
WHITESPACE
|
85
91
|
WITH
|
86
92
|
WORD
|
87
|
-
].map { |x| [x, x] }
|
93
|
+
].map { |x| [x, x] }.to_h
|
88
94
|
|
89
95
|
class ScanError < StandardError; end
|
90
96
|
|
@@ -151,9 +157,9 @@ module SrlRuby
|
|
151
157
|
col = scanner.pos - aLexeme.size - @line_start + 1
|
152
158
|
pos = Rley::Lexical::Position.new(@lineno, col)
|
153
159
|
token = Rley::Lexical::Token.new(aLexeme, aSymbolName, pos)
|
154
|
-
rescue StandardError =>
|
160
|
+
rescue StandardError => e
|
155
161
|
puts "Failing with '#{aSymbolName}' and '#{aLexeme}'"
|
156
|
-
raise
|
162
|
+
raise e
|
157
163
|
end
|
158
164
|
|
159
165
|
return token
|
data/lib/srl_ruby/version.rb
CHANGED
data/lib/srl_ruby.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# File: rule_file_grammar.rb
|
2
4
|
require 'rley' # Load the Rley gem
|
3
5
|
|
@@ -5,20 +7,20 @@ require 'rley' # Load the Rley gem
|
|
5
7
|
# [File format](https://github.com/SimpleRegex/Test-Rules/blob/master/README.md)
|
6
8
|
########################################
|
7
9
|
# Define a grammar for basic arithmetical expressions
|
8
|
-
builder = Rley::
|
10
|
+
builder = Rley::grammar_builder do
|
9
11
|
# Punctuation
|
10
12
|
add_terminals('COLON', 'DASH')
|
11
13
|
|
12
14
|
# Keywords
|
13
15
|
add_terminals('CAPTURE', 'FOR')
|
14
|
-
add_terminals('MATCH
|
16
|
+
add_terminals('MATCH', 'NO', 'SRL')
|
15
17
|
|
16
18
|
# Literals
|
17
19
|
add_terminals('INTEGER', 'STRING_LIT')
|
18
20
|
add_terminals('IDENTIFIER', 'SRL_SOURCE')
|
19
21
|
|
20
22
|
rule('rule_file' => 'srl_heading srl_tests').as 'start_rule'
|
21
|
-
rule('srl_heading' => 'SRL
|
23
|
+
rule('srl_heading' => 'SRL SRL_SOURCE').as 'srl_source'
|
22
24
|
rule('srl_tests' => 'srl_tests single_test').as 'test_list'
|
23
25
|
rule('srl_tests' => 'single_test').as 'one_test'
|
24
26
|
rule('single_test' => 'atomic_test').as 'single_atomic_test'
|
@@ -26,8 +28,8 @@ builder = Rley::Syntax::GrammarBuilder.new do
|
|
26
28
|
rule('atomic_test' => 'match_test').as 'atomic_match'
|
27
29
|
rule('atomic_test' => 'no_match_test').as 'atomic_no_match'
|
28
30
|
rule('compound_test' => 'capture_test').as 'compound_capture'
|
29
|
-
rule('match_test' => 'MATCH
|
30
|
-
rule('no_match_test' => 'NO MATCH
|
31
|
+
rule('match_test' => 'MATCH STRING_LIT').as 'match_string'
|
32
|
+
rule('no_match_test' => 'NO MATCH STRING_LIT').as 'no_match_string'
|
31
33
|
rule('capture_test' => 'capture_heading capture_expectations').as 'capture_test'
|
32
34
|
rule('capture_heading' => 'CAPTURE FOR STRING_LIT COLON').as 'capture_string'
|
33
35
|
rule('capture_expectations' => 'capture_expectations single_expectation').as 'assertion_list'
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# File: rule_tokenizer.rb
|
2
4
|
# Tokenizer for SimpleRegex Test-Rule files
|
3
5
|
# [File format](https://github.com/SimpleRegex/Test-Rules/blob/master/README.md)
|
@@ -14,8 +16,13 @@ module Acceptance
|
|
14
16
|
# Delimiters: parentheses '(' and ')'
|
15
17
|
# Separators: comma (optional)
|
16
18
|
class RuleFileTokenizer
|
19
|
+
# @return [StringScanner]
|
17
20
|
attr_reader(:scanner)
|
21
|
+
|
22
|
+
# @return [Integer] current line number
|
18
23
|
attr_reader(:lineno)
|
24
|
+
|
25
|
+
# @return [Integer] offset of start of current line within input
|
19
26
|
attr_reader(:line_start)
|
20
27
|
|
21
28
|
# Can be :default, :expecting_srl
|
@@ -80,7 +87,7 @@ module Acceptance
|
|
80
87
|
elsif (lexeme = scanner.scan(/[0-9]+/))
|
81
88
|
token = build_token('INTEGER', lexeme)
|
82
89
|
elsif (lexeme = scanner.scan(/srl:|match:/))
|
83
|
-
token = build_token(@@keywords[lexeme], lexeme)
|
90
|
+
token = build_token(@@keywords[lexeme].chop, lexeme.chop)
|
84
91
|
@state = :expecting_srl if lexeme == 'srl:'
|
85
92
|
elsif (lexeme = scanner.scan(/[a-zA-Z_][a-zA-Z0-9_]*/))
|
86
93
|
keyw = @@keywords[lexeme]
|
@@ -111,9 +118,9 @@ module Acceptance
|
|
111
118
|
col = scanner.pos - aLexeme.size - @line_start + 1
|
112
119
|
pos = Rley::Lexical::Position.new(@lineno, col)
|
113
120
|
token = Rley::Lexical::Token.new(aLexeme, aSymbolName, pos)
|
114
|
-
rescue StandardError =>
|
121
|
+
rescue StandardError => e
|
115
122
|
puts "Failing with '#{aSymbolName}' and '#{aLexeme}'"
|
116
|
-
raise
|
123
|
+
raise e
|
117
124
|
end
|
118
125
|
|
119
126
|
return token
|
@@ -1,9 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# File: character_spec.rb
|
2
4
|
require_relative '../spec_helper' # Use the RSpec test framework
|
3
5
|
require_relative '../../lib/regex/character'
|
4
6
|
|
5
7
|
module Regex # Open this namespace, to get rid of scope qualifiers
|
6
8
|
describe Character do
|
9
|
+
# rubocop: disable Lint/ConstantDefinitionInBlock
|
10
|
+
|
7
11
|
# This constant holds an arbitrary selection of characters
|
8
12
|
SampleChars = [?a, ?\0, ?\u0107].freeze
|
9
13
|
|
@@ -85,6 +89,8 @@ module Regex # Open this namespace, to get rid of scope qualifiers
|
|
85
89
|
|
86
90
|
# Try with our escape sequence samples
|
87
91
|
(SampleDigrams + SampleNumEscs).each do |escape_seq|
|
92
|
+
|
93
|
+
# Build a string from escape sequence literal
|
88
94
|
expectation = String.class_eval(%Q|"#{escape_seq}"|, __FILE__, __LINE__)
|
89
95
|
new_ch = Character.new(escape_seq).to_str
|
90
96
|
new_ch == expectation
|
@@ -109,11 +115,20 @@ module Regex # Open this namespace, to get rid of scope qualifiers
|
|
109
115
|
|
110
116
|
# Try with our escape sequence samples
|
111
117
|
(SampleDigrams + SampleNumEscs).each do |escape_seq|
|
118
|
+
|
119
|
+
# Get ordinal value of given escape sequence
|
112
120
|
expectation = String.class_eval(%Q|"#{escape_seq}".ord()|, __FILE__, __LINE__)
|
113
121
|
expect(Character.new(escape_seq).codepoint).to eq(expectation)
|
114
122
|
end
|
115
123
|
end
|
116
124
|
|
125
|
+
# Create a module that re-defines the existing to_s method
|
126
|
+
module Tweak_to_s
|
127
|
+
def to_s # Overwrite the existing to_s method
|
128
|
+
?\u03a3
|
129
|
+
end
|
130
|
+
end # module
|
131
|
+
|
117
132
|
it 'should known whether it is equal to another Object' do
|
118
133
|
newOne = Character.new(?\u03a3)
|
119
134
|
|
@@ -145,12 +160,6 @@ module Regex # Open this namespace, to get rid of scope qualifiers
|
|
145
160
|
expect(simulator).to receive(:to_s).and_return(?\u03a3)
|
146
161
|
expect(newOne).to eq(simulator)
|
147
162
|
|
148
|
-
# Create a module that re-defines the existing to_s method
|
149
|
-
module Tweak_to_s
|
150
|
-
def to_s # Overwrite the existing to_s method
|
151
|
-
?\u03a3
|
152
|
-
end
|
153
|
-
end # module
|
154
163
|
weird = Object.new
|
155
164
|
weird.extend(Tweak_to_s)
|
156
165
|
expect(newOne).to eq(weird)
|
@@ -164,6 +173,7 @@ module Regex # Open this namespace, to get rid of scope qualifiers
|
|
164
173
|
expect(ch2.explain).to eq("the character '\u03a3'")
|
165
174
|
end
|
166
175
|
end # context
|
176
|
+
# rubocop: enable Lint/ConstantDefinitionInBlock
|
167
177
|
end # describe
|
168
178
|
end # module
|
169
179
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# File: multiplicity_spec.rb
|
2
4
|
|
3
5
|
require_relative '../spec_helper' # Use the RSpec test framework
|
@@ -21,6 +23,7 @@ module Regex # This module is used as a namespace
|
|
21
23
|
end
|
22
24
|
|
23
25
|
context 'Provided services' do
|
26
|
+
# rubocop: disable Style/CombinableLoops
|
24
27
|
it 'should know its text representation' do
|
25
28
|
policy2text = { greedy: '', lazy: '?', possessive: '+' }
|
26
29
|
|
@@ -71,6 +74,7 @@ module Regex # This module is used as a namespace
|
|
71
74
|
end
|
72
75
|
end
|
73
76
|
end
|
77
|
+
# rubocop: enable Style/CombinableLoops
|
74
78
|
end
|
75
79
|
end
|
76
80
|
end # module
|
data/spec/spec_helper.rb
CHANGED
data/spec/srl_ruby_spec.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'spec_helper' # Use the RSpec framework
|
2
4
|
require_relative '../lib/srl_ruby'
|
3
5
|
|
@@ -224,7 +226,7 @@ SRL
|
|
224
226
|
let(:prefix) { 'letter from p to t ' }
|
225
227
|
|
226
228
|
it "should parse 'once' syntax" do
|
227
|
-
regexp = SrlRuby.parse(prefix
|
229
|
+
regexp = SrlRuby.parse("#{prefix}once")
|
228
230
|
expect(regexp.source).to eq('[p-t]{1}')
|
229
231
|
end
|
230
232
|
|
@@ -244,26 +246,26 @@ SRL
|
|
244
246
|
end
|
245
247
|
|
246
248
|
it "should parse 'between ... and ... times' syntax" do
|
247
|
-
regexp = SrlRuby.parse(prefix
|
249
|
+
regexp = SrlRuby.parse("#{prefix}between 2 and 4 times")
|
248
250
|
expect(regexp.source).to eq('[p-t]{2,4}')
|
249
251
|
|
250
252
|
# Dropping 'times' keyword is a shorter alternative syntax
|
251
|
-
regexp = SrlRuby.parse(prefix
|
253
|
+
regexp = SrlRuby.parse("#{prefix}between 2 and 4")
|
252
254
|
expect(regexp.source).to eq('[p-t]{2,4}')
|
253
255
|
end
|
254
256
|
|
255
257
|
it "should parse 'once or more' syntax" do
|
256
|
-
regexp = SrlRuby.parse(prefix
|
258
|
+
regexp = SrlRuby.parse("#{prefix}once or more")
|
257
259
|
expect(regexp.source).to eq('[p-t]+')
|
258
260
|
end
|
259
261
|
|
260
262
|
it "should parse 'never or more' syntax" do
|
261
|
-
regexp = SrlRuby.parse(prefix
|
263
|
+
regexp = SrlRuby.parse("#{prefix}never or more")
|
262
264
|
expect(regexp.source).to eq('[p-t]*')
|
263
265
|
end
|
264
266
|
|
265
267
|
it "should parse 'at least ... times' syntax" do
|
266
|
-
regexp = SrlRuby.parse(prefix
|
268
|
+
regexp = SrlRuby.parse("#{prefix}at least 10 times")
|
267
269
|
expect(regexp.source).to eq('[p-t]{10,}')
|
268
270
|
end
|
269
271
|
end # context
|
data/srl_ruby.gemspec
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
lib = File.expand_path('../lib', __FILE__)
|
2
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
5
|
require 'srl_ruby/version'
|
@@ -63,14 +65,14 @@ SUMMARY
|
|
63
65
|
spec.require_paths = ['lib']
|
64
66
|
PkgExtending.pkg_files(spec)
|
65
67
|
PkgExtending.pkg_documentation(spec)
|
66
|
-
spec.required_ruby_version = '>= 2.
|
68
|
+
spec.required_ruby_version = '>= 2.5.0'
|
67
69
|
|
68
70
|
# Runtime dependencies
|
69
|
-
spec.add_dependency 'rley', '~> 0.
|
71
|
+
spec.add_dependency 'rley', '~> 0.8.08'
|
70
72
|
|
71
73
|
# Development dependencies
|
72
|
-
spec.add_development_dependency 'bundler', '~>
|
74
|
+
spec.add_development_dependency 'bundler', '~> 2.2.0'
|
73
75
|
spec.add_development_dependency 'cucumber', '>= 2.2.0'
|
74
|
-
spec.add_development_dependency 'rake', '~>
|
76
|
+
spec.add_development_dependency 'rake', '~> 12.0'
|
75
77
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
76
78
|
end
|