srl_ruby 0.4.4 → 0.4.8

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.
Files changed (58) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +278 -22
  3. data/CHANGELOG.md +39 -0
  4. data/Gemfile +2 -0
  5. data/LICENSE.txt +1 -1
  6. data/README.md +1 -1
  7. data/Rakefile +3 -0
  8. data/appveyor.yml +15 -14
  9. data/bin/srl2ruby +17 -12
  10. data/bin/srl2ruby_cli_parser.rb +6 -6
  11. data/features/lib/step_definitions/srl_testing_steps.rb +2 -0
  12. data/features/lib/support/env..rb +2 -0
  13. data/lib/regex/abstract_method.rb +2 -0
  14. data/lib/regex/alternation.rb +3 -3
  15. data/lib/regex/anchor.rb +3 -0
  16. data/lib/regex/atomic_expression.rb +2 -0
  17. data/lib/regex/capturing_group.rb +8 -3
  18. data/lib/regex/char_class.rb +4 -2
  19. data/lib/regex/char_range.rb +4 -3
  20. data/lib/regex/char_shorthand.rb +3 -0
  21. data/lib/regex/character.rb +7 -2
  22. data/lib/regex/compound_expression.rb +2 -0
  23. data/lib/regex/concatenation.rb +3 -1
  24. data/lib/regex/expression.rb +6 -1
  25. data/lib/regex/lookaround.rb +3 -1
  26. data/lib/regex/match_option.rb +2 -0
  27. data/lib/regex/monadic_expression.rb +2 -0
  28. data/lib/regex/multiplicity.rb +9 -9
  29. data/lib/regex/non_capturing_group.rb +3 -1
  30. data/lib/regex/polyadic_expression.rb +4 -0
  31. data/lib/regex/quantifiable.rb +3 -1
  32. data/lib/regex/raw_expression.rb +2 -0
  33. data/lib/regex/repetition.rb +2 -0
  34. data/lib/regex/wildcard.rb +2 -5
  35. data/lib/srl_ruby/ast_builder.rb +82 -115
  36. data/lib/srl_ruby/grammar.rb +80 -92
  37. data/lib/srl_ruby/regex_repr.rb +2 -0
  38. data/lib/srl_ruby/tokenizer.rb +11 -5
  39. data/lib/srl_ruby/version.rb +3 -1
  40. data/lib/srl_ruby.rb +2 -0
  41. data/spec/acceptance/srl_test_suite_spec.rb +2 -0
  42. data/spec/acceptance/support/rule_file_ast_builder.rb +2 -0
  43. data/spec/acceptance/support/rule_file_grammar.rb +7 -5
  44. data/spec/acceptance/support/rule_file_nodes.rb +2 -0
  45. data/spec/acceptance/support/rule_file_parser.rb +2 -0
  46. data/spec/acceptance/support/rule_file_tokenizer.rb +11 -4
  47. data/spec/regex/atomic_expression_spec.rb +2 -0
  48. data/spec/regex/character_spec.rb +12 -6
  49. data/spec/regex/match_option_spec.rb +2 -0
  50. data/spec/regex/monadic_expression_spec.rb +2 -0
  51. data/spec/regex/multiplicity_spec.rb +4 -0
  52. data/spec/regex/repetition_spec.rb +2 -0
  53. data/spec/spec_helper.rb +2 -0
  54. data/spec/srl_ruby/srl_ruby_spec.rb +2 -0
  55. data/spec/srl_ruby/tokenizer_spec.rb +2 -0
  56. data/spec/srl_ruby_spec.rb +8 -6
  57. data/srl_ruby.gemspec +7 -5
  58. metadata +16 -16
@@ -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::Syntax::GrammarBuilder.new do
8
+ builder = Rley::Notation::GrammarBuilder.new 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').as 'start_rule'
33
- rule('expression' => %w[pattern flags]).as 'flagged_expr'
34
- rule('expression' => 'pattern').as 'simple_expr'
35
- rule('pattern' => %w[pattern separator sub_pattern]).as 'pattern_sequence'
36
- rule('pattern' => 'sub_pattern').as 'basic_pattern'
37
- rule('sub_pattern' => 'quantifiable').as 'quantifiable_sub_pattern'
38
- rule('sub_pattern' => 'assertion').as 'assertion_sub_pattern'
39
- rule('separator' => 'COMMA').as 'comma_separator'
40
- rule('separator' => []).as 'void_separator'
41
- rule('flags' => %w[flags separator single_flag]).as 'flag_sequence'
42
- rule('flags' => %w[separator single_flag]).as 'flag_simple'
43
- rule('single_flag' => %w[CASE INSENSITIVE]).as 'case_insensitive'
44
- rule('single_flag' => %w[MULTI LINE]).as 'multi_line'
45
- rule('single_flag' => %w[ALL LAZY]).as 'all_lazy'
46
- rule('quantifiable' => %w[begin_anchor anchorable end_anchor]).as 'pinned_quantifiable'
47
- rule('quantifiable' => %w[begin_anchor anchorable]).as 'begin_anchor_quantifiable'
48
- rule('quantifiable' => %w[anchorable end_anchor]).as 'end_anchor_quantifiable'
49
- rule('quantifiable' => 'anchorable').as 'simple_quantifiable'
50
- rule('begin_anchor' => %w[STARTS WITH]).as 'starts_with'
51
- rule('begin_anchor' => %w[BEGIN WITH]).as 'begin_with'
52
- rule('end_anchor' => %w[separator MUST END]).as 'end_anchor'
53
- rule('anchorable' => 'assertable').as 'simple_anchorable'
54
- rule('assertion' => %w[IF FOLLOWED BY assertable]).as 'if_followed'
55
- rule('assertion' => %w[IF NOT FOLLOWED BY assertable]).as 'if_not_followed'
56
- rule('assertion' => %w[IF ALREADY HAD assertable]).as 'if_had'
57
- rule('assertion' => %w[IF NOT ALREADY HAD assertable]).as 'if_not_had'
58
- rule('assertable' => 'term').as 'simple_assertable'
59
- rule('assertable' => %w[term quantifier]).as 'quantified_assertable'
60
- rule('term' => 'atom').as 'atom_term'
61
- rule('term' => 'alternation').as 'alternation_term'
62
- rule('term' => 'grouping').as 'grouping_term'
63
- rule('term' => 'capturing_group').as 'capturing_group_atom'
64
- rule('atom' => 'letter_range').as 'letter_range_atom'
65
- rule('atom' => 'digit_range').as 'digit_range_atom'
66
- rule('atom' => 'character_class').as 'character_class_atom'
67
- rule('atom' => 'special_char').as 'special_char_atom'
68
- rule('atom' => 'literal').as 'literal_atom'
69
- rule('atom' => 'raw').as 'raw_atom'
70
- rule('letter_range' => %w[LETTER FROM LETTER_LIT TO LETTER_LIT]).as 'lowercase_from_to'
71
- rule('letter_range' => %w[UPPERCASE LETTER FROM LETTER_LIT TO LETTER_LIT]).as 'uppercase_from_to'
72
- rule('letter_range' => 'LETTER').as 'any_lowercase'
73
- rule('letter_range' => %w[UPPERCASE LETTER]).as 'any_uppercase'
74
- rule('digit_range' => %w[digit_or_number FROM DIGIT_LIT TO DIGIT_LIT]).as 'digits_from_to'
75
- rule('character_class' => %w[ANY CHARACTER]).as 'any_character'
76
- rule('character_class' => %w[NO CHARACTER]).as 'no_character'
77
- rule('character_class' => 'digit_or_number').as 'digit'
78
- rule('character_class' => %w[NO DIGIT]).as 'non_digit'
79
- rule('character_class' => 'WHITESPACE').as 'whitespace'
80
- rule('character_class' => %w[NO WHITESPACE]).as 'no_whitespace'
81
- rule('character_class' => 'ANYTHING').as 'anything'
82
- rule('character_class' => %w[ONE OF cclass]).as 'one_of'
83
- rule('character_class' => %w[NONE OF cclass]).as 'none_of'
84
- rule('cclass' => 'STRING_LIT').as 'quoted_cclass' # Preferred syntax
85
- rule('cclass' => 'INTEGER').as 'digits_cclass'
86
- rule('cclass' => 'IDENTIFIER').as 'identifier_cclass'
87
- rule('cclass' => 'CHAR_CLASS').as 'unquoted_cclass'
88
- rule('special_char' => 'TAB').as 'tab'
89
- rule('special_char' => 'VERTICAL TAB').as 'vtab'
90
- rule('special_char' => 'BACKSLASH').as 'backslash'
91
- rule('special_char' => %w[NEW LINE]).as 'new_line'
92
- rule('special_char' => %w[CARRIAGE RETURN]).as 'carriage_return'
93
- rule('special_char' => %w[WORD]).as 'word'
94
- rule('special_char' => %w[NO WORD]).as 'no_word'
95
- rule('literal' => %w[LITERALLY STRING_LIT]).as 'literally'
96
- rule('raw' => 'RAW STRING_LIT').as 'raw_literal'
97
- rule('alternation' => %w[any_or_either OF LPAREN alternatives RPAREN]).as 'any_of'
98
- rule('alternatives' => %w[alternatives separator quantifiable]).as 'alternative_list'
99
- rule('alternatives' => 'quantifiable').as 'simple_alternative'
100
- rule('any_or_either' => 'ANY').as 'any_keyword'
101
- rule('any_or_either' => 'EITHER').as 'either_keyword'
102
- rule('grouping' => %w[LPAREN pattern RPAREN]).as 'grouping_parenthenses'
103
- rule('capturing_group' => %w[CAPTURE assertable]).as 'capture'
104
- rule('capturing_group' => %w[CAPTURE assertable UNTIL assertable]).as 'capture_until'
105
- rule('capturing_group' => %w[CAPTURE assertable AS var_name]).as 'named_capture'
106
- rule('capturing_group' => %w[CAPTURE assertable AS var_name UNTIL assertable]).as 'named_capture_until'
107
- rule('var_name' => 'STRING_LIT').as 'var_name'
108
- rule('var_name' => 'IDENTIFIER').as 'var_ident' # capture name not enclosed between quotes
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../regex/character'
2
4
  require_relative '../regex/char_range'
3
5
  require_relative '../regex/concatenation'
@@ -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] } .to_h
93
+ ].map { |x| [x, x] }.to_h
88
94
 
89
95
  class ScanError < StandardError; end
90
96
 
@@ -132,7 +138,7 @@ module SrlRuby
132
138
  token = build_token('LETTER_LIT', lexeme)
133
139
  elsif (lexeme = scanner.scan(/[a-zA-Z_][a-zA-Z0-9_]+/))
134
140
  keyw = @@keywords[lexeme.upcase]
135
- tok_type = keyw ? keyw : 'IDENTIFIER'
141
+ tok_type = keyw || 'IDENTIFIER'
136
142
  token = build_token(tok_type, lexeme)
137
143
  elsif (lexeme = scanner.scan(/[^,"\s]{2,}/))
138
144
  token = build_token('CHAR_CLASS', lexeme)
@@ -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 => exc
160
+ rescue StandardError => e
155
161
  puts "Failing with '#{aSymbolName}' and '#{aLexeme}'"
156
- raise exc
162
+ raise e
157
163
  end
158
164
 
159
165
  return token
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SrlRuby
2
- VERSION = '0.4.4'.freeze
4
+ VERSION = '0.4.8'
3
5
  end
data/lib/srl_ruby.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative './srl_ruby/version'
2
4
  require_relative './srl_ruby/tokenizer'
3
5
  require_relative './srl_ruby/grammar'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../spec_helper'
2
4
  require_relative './support/rule_file_parser'
3
5
  require_relative '../../lib/srl_ruby'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'rule_file_nodes'
2
4
 
3
5
  module Acceptance
@@ -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::Syntax::GrammarBuilder.new do
10
+ builder = Rley::Notation::GrammarBuilder.new 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:', 'NO', 'SRL:')
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: SRL_SOURCE').as 'srl_source'
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: STRING_LIT').as 'match_string'
30
- rule('no_match_test' => 'NO MATCH: STRING_LIT').as 'no_match_string'
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
  # Classes that implement nodes of Abstract Syntax Trees (AST) representing
2
4
  # rule file contents.
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'rule_file_tokenizer'
2
4
  require_relative 'rule_file_grammar'
3
5
  require_relative 'rule_file_ast_builder'
@@ -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,11 +87,11 @@ 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]
87
- token_type = keyw ? keyw : 'IDENTIFIER'
94
+ token_type = keyw || 'IDENTIFIER'
88
95
  token = build_token(token_type, lexeme)
89
96
  elsif (lexeme = scanner.scan(/"([^"]|\\")*"/)) # Double quotes literal?
90
97
  unquoted = lexeme.gsub(/(^")|("$)/, '')
@@ -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 => exc
121
+ rescue StandardError => e
115
122
  puts "Failing with '#{aSymbolName}' and '#{aLexeme}'"
116
- raise exc
123
+ raise e
117
124
  end
118
125
 
119
126
  return token
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # File: atomic_expression_spec.rb
2
4
  require_relative '../spec_helper' # Use the RSpec test framework
3
5
  require_relative '../../lib/regex/atomic_expression'
@@ -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
 
@@ -114,6 +118,13 @@ module Regex # Open this namespace, to get rid of scope qualifiers
114
118
  end
115
119
  end
116
120
 
121
+ # Create a module that re-defines the existing to_s method
122
+ module Tweak_to_s
123
+ def to_s # Overwrite the existing to_s method
124
+ ?\u03a3
125
+ end
126
+ end # module
127
+
117
128
  it 'should known whether it is equal to another Object' do
118
129
  newOne = Character.new(?\u03a3)
119
130
 
@@ -145,12 +156,6 @@ module Regex # Open this namespace, to get rid of scope qualifiers
145
156
  expect(simulator).to receive(:to_s).and_return(?\u03a3)
146
157
  expect(newOne).to eq(simulator)
147
158
 
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
159
  weird = Object.new
155
160
  weird.extend(Tweak_to_s)
156
161
  expect(newOne).to eq(weird)
@@ -164,6 +169,7 @@ module Regex # Open this namespace, to get rid of scope qualifiers
164
169
  expect(ch2.explain).to eq("the character '\u03a3'")
165
170
  end
166
171
  end # context
172
+ # rubocop: enable Lint/ConstantDefinitionInBlock
167
173
  end # describe
168
174
  end # module
169
175
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # File: match_option_spec.rb
2
4
 
3
5
  require_relative '../spec_helper' # Use the RSpec test framework
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # File: monadic_expression_spec.rb
2
4
  require_relative '../spec_helper' # Use the RSpec test framework
3
5
  require_relative '../../lib/regex/monadic_expression'
@@ -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