sequitur 0.1.22 → 0.1.24
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/.rubocop.yml +11 -180
- data/CHANGELOG.md +11 -1
- data/LICENSE.txt +1 -1
- data/Rakefile +0 -2
- data/examples/integer_sample.rb +1 -2
- data/examples/porridge.rb +10 -10
- data/examples/simple_case.rb +1 -1
- data/examples/symbol_sample.rb +1 -1
- data/examples/word_sample.rb +5 -6
- data/lib/sequitur/constants.rb +5 -2
- data/lib/sequitur/digram.rb +3 -3
- data/lib/sequitur/dynamic_grammar.rb +4 -5
- data/lib/sequitur/formatter/base_formatter.rb +1 -1
- data/lib/sequitur/formatter/base_text.rb +3 -7
- data/lib/sequitur/formatter/debug.rb +0 -1
- data/lib/sequitur/grammar_visitor.rb +1 -1
- data/lib/sequitur/production.rb +200 -205
- data/lib/sequitur/production_ref.rb +9 -12
- data/lib/sequitur/sequitur_grammar.rb +135 -137
- data/lib/sequitur/symbol_sequence.rb +24 -27
- data/lib/sequitur.rb +4 -5
- data/spec/sequitur/digram_spec.rb +13 -12
- data/spec/sequitur/dynamic_grammar_spec.rb +5 -11
- data/spec/sequitur/formatter/base_text_spec.rb +70 -72
- data/spec/sequitur/formatter/debug_spec.rb +90 -92
- data/spec/sequitur/grammar_visitor_spec.rb +70 -71
- data/spec/sequitur/production_ref_spec.rb +92 -92
- data/spec/sequitur/production_spec.rb +30 -34
- data/spec/sequitur/sequitur_grammar_spec.rb +48 -49
- data/spec/sequitur/symbol_sequence_spec.rb +102 -105
- data/spec/spec_helper.rb +0 -15
- metadata +18 -60
- data/.simplecov +0 -7
- data/.travis.yml +0 -29
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a1ba8348f20a1e800b1c7001090916dbe05159177471452fdcfa8925bc975431
|
|
4
|
+
data.tar.gz: a8002cab5a1f7ae7b20b347f4a5f79e92a2f979dca1fad2dad83e153f5969d22
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2a116b242f218d0c08740a0432b641f88dbaa7f65dd67b02a5339be208927c835db4965d6e3ede344d7d93a4bbea6d4468692c4b237f1f18a8bbd3f6ffb54037
|
|
7
|
+
data.tar.gz: 2b7ea3e4acf58cb45ed3c0b7081a35201c2a8aa5285e163e9845fd82f082e7dcfb563a063d566c2561bb81944cefec6a67d0d2203b2080cb12fd73f6ace3c53e
|
data/.rubocop.yml
CHANGED
|
@@ -1,199 +1,30 @@
|
|
|
1
1
|
AllCops:
|
|
2
2
|
Exclude:
|
|
3
|
-
- 'exp/**/*'
|
|
4
3
|
- 'lab/**/*'
|
|
5
|
-
|
|
6
|
-
Layout/CaseIndentation:
|
|
7
|
-
Enabled: false
|
|
8
|
-
|
|
9
|
-
Layout/ClosingHeredocIndentation:
|
|
10
|
-
Enabled: false
|
|
11
|
-
|
|
12
|
-
Layout/CommentIndentation:
|
|
13
|
-
Enabled: false
|
|
14
|
-
|
|
15
|
-
Layout/ElseAlignment:
|
|
16
|
-
Enabled: false
|
|
17
|
-
|
|
18
|
-
Layout/EmptyLines:
|
|
19
|
-
Enabled: false
|
|
20
|
-
|
|
21
|
-
Layout/EndAlignment:
|
|
22
|
-
Enabled: false
|
|
23
|
-
|
|
4
|
+
|
|
24
5
|
Layout/EndOfLine:
|
|
25
|
-
Enabled:
|
|
26
|
-
EnforcedStyle: lf
|
|
27
|
-
|
|
28
|
-
Layout/IndentationWidth:
|
|
29
|
-
Enabled: false
|
|
30
|
-
|
|
31
|
-
Layout/IndentationConsistency:
|
|
32
|
-
Enabled: true
|
|
33
|
-
|
|
34
|
-
Layout/IndentHeredoc:
|
|
35
|
-
Enabled: false
|
|
36
|
-
|
|
37
|
-
Layout/MultilineHashBraceLayout:
|
|
38
|
-
Enabled: true
|
|
39
|
-
|
|
40
|
-
Layout/SpaceAroundOperators:
|
|
41
|
-
Enabled: true
|
|
42
|
-
|
|
43
|
-
Layout/SpaceInsideParens:
|
|
44
|
-
Enabled: true
|
|
45
|
-
|
|
46
|
-
Layout/Tab:
|
|
47
|
-
Enabled: true
|
|
48
|
-
|
|
49
|
-
Layout/TrailingBlankLines:
|
|
50
|
-
Enabled: true
|
|
51
|
-
|
|
52
|
-
Layout/TrailingWhitespace:
|
|
53
|
-
Enabled: true
|
|
54
|
-
|
|
55
|
-
Lint/Loop:
|
|
56
|
-
Enabled: true
|
|
57
|
-
|
|
58
|
-
Lint/RescueException:
|
|
59
|
-
Enabled: true
|
|
60
|
-
|
|
61
|
-
Lint/UnusedMethodArgument:
|
|
62
|
-
Enabled: true
|
|
63
|
-
|
|
64
|
-
Lint/UselessAccessModifier:
|
|
65
|
-
Enabled: true
|
|
66
|
-
|
|
67
|
-
Lint/Void:
|
|
68
|
-
Enabled: false
|
|
69
|
-
|
|
70
|
-
Lint/UselessAssignment:
|
|
71
|
-
Enabled: true
|
|
6
|
+
Enabled: false # Make source portable!
|
|
72
7
|
|
|
73
8
|
Metrics/AbcSize:
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
Metrics/BlockLength:
|
|
77
|
-
Enabled: true
|
|
78
|
-
Max: 350
|
|
9
|
+
Max: 22
|
|
79
10
|
|
|
80
11
|
Metrics/ClassLength:
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
12
|
+
Max: 150
|
|
13
|
+
|
|
84
14
|
Metrics/CyclomaticComplexity:
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
Metrics/LineLength:
|
|
88
|
-
Enabled: false
|
|
89
|
-
Max: 90
|
|
15
|
+
Max: 10
|
|
90
16
|
|
|
91
17
|
Metrics/MethodLength:
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
Metrics/ModuleLength:
|
|
96
|
-
Enabled: true
|
|
97
|
-
Max: 500
|
|
98
|
-
|
|
18
|
+
Max: 50
|
|
19
|
+
|
|
99
20
|
Metrics/PerceivedComplexity:
|
|
100
|
-
|
|
21
|
+
Max: 10
|
|
101
22
|
|
|
102
|
-
Naming/
|
|
23
|
+
Naming/MethodParameterName:
|
|
103
24
|
Enabled: false
|
|
104
|
-
|
|
105
|
-
Naming/ClassAndModuleCamelCase:
|
|
106
|
-
Enabled: false
|
|
107
|
-
|
|
108
|
-
Naming/UncommunicativeBlockParamName:
|
|
109
|
-
Enabled: true
|
|
110
25
|
|
|
111
|
-
Naming/UncommunicativeMethodParamName:
|
|
112
|
-
Enabled: false
|
|
113
|
-
|
|
114
26
|
Naming/VariableName:
|
|
115
27
|
Enabled: false
|
|
116
28
|
|
|
117
|
-
Style/Alias:
|
|
118
|
-
Enabled: true
|
|
119
|
-
|
|
120
|
-
Layout/AlignHash:
|
|
121
|
-
Enabled: false
|
|
122
|
-
|
|
123
|
-
Style/AsciiComments:
|
|
124
|
-
Enabled: false
|
|
125
|
-
|
|
126
|
-
Style/BarePercentLiterals:
|
|
127
|
-
Enabled: false
|
|
128
|
-
|
|
129
|
-
Style/BlockComments:
|
|
130
|
-
Enabled: false
|
|
131
|
-
|
|
132
|
-
Style/CharacterLiteral:
|
|
133
|
-
Enabled: false
|
|
134
|
-
|
|
135
|
-
Style/ClassCheck:
|
|
136
|
-
Enabled: false
|
|
137
|
-
|
|
138
|
-
Style/ClassVars:
|
|
139
|
-
Enabled: false
|
|
140
|
-
|
|
141
|
-
Style/ColonMethodCall:
|
|
142
|
-
Enabled: false
|
|
143
|
-
|
|
144
|
-
Style/CommentAnnotation:
|
|
145
|
-
Enabled: false
|
|
146
|
-
|
|
147
29
|
Style/CommentedKeyword:
|
|
148
|
-
Enabled: false
|
|
149
|
-
|
|
150
|
-
Style/ConditionalAssignment:
|
|
151
|
-
Enabled: false
|
|
152
|
-
|
|
153
|
-
Style/DefWithParentheses:
|
|
154
|
-
Enabled: true
|
|
155
|
-
|
|
156
|
-
Style/Documentation:
|
|
157
|
-
Enabled: false
|
|
158
|
-
|
|
159
|
-
Style/ExpandPathArguments:
|
|
160
|
-
Enabled: false
|
|
161
|
-
|
|
162
|
-
Style/GuardClause:
|
|
163
|
-
Enabled: false
|
|
164
|
-
|
|
165
|
-
Style/IfUnlessModifier:
|
|
166
|
-
Enabled: false
|
|
167
|
-
|
|
168
|
-
Style/InverseMethods:
|
|
169
|
-
Enabled: true
|
|
170
|
-
|
|
171
|
-
Style/Next:
|
|
172
|
-
Enabled: false
|
|
173
|
-
|
|
174
|
-
Style/RaiseArgs:
|
|
175
|
-
Enabled: true
|
|
176
|
-
|
|
177
|
-
Style/RedundantReturn:
|
|
178
|
-
Enabled: false
|
|
179
|
-
|
|
180
|
-
Style/RedundantSelf:
|
|
181
|
-
Enabled: true
|
|
182
|
-
|
|
183
|
-
Style/RegexpLiteral:
|
|
184
|
-
Enabled: false
|
|
185
|
-
|
|
186
|
-
Style/PercentLiteralDelimiters:
|
|
187
|
-
Enabled: false
|
|
188
|
-
|
|
189
|
-
Style/StderrPuts:
|
|
190
|
-
Enabled: false
|
|
191
|
-
|
|
192
|
-
Style/StringLiterals:
|
|
193
|
-
Enabled: true
|
|
194
|
-
|
|
195
|
-
Style/TernaryParentheses:
|
|
196
|
-
Enabled: false
|
|
197
|
-
|
|
198
|
-
Style/UnlessElse:
|
|
199
|
-
Enabled: false
|
|
30
|
+
Enabled: false
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
|
+
## [0.1.24] - 2021-07-01
|
|
2
|
+
- Code restyling to please rubocop 1.53.1
|
|
3
|
+
|
|
4
|
+
## [0.1.23] - 2021-09-04
|
|
5
|
+
- Remove dependencies towards `coverall`, `simplecov`
|
|
6
|
+
- Code restyling to please rubocop 1.19.1
|
|
7
|
+
|
|
8
|
+
* [CHANGE] File 'sequitur.gemspec' Remove dependencies towards `coverall`, `simplecov`
|
|
9
|
+
* [CHANGE] File 'sequitur.gemspec' Ruby version must be 2.5+
|
|
10
|
+
|
|
1
11
|
## [0.1.22] - 2019-08-18
|
|
2
|
-
- Code refactoring to use string frozen magic comments (as a consequence,
|
|
12
|
+
- Code refactoring to use string frozen magic comments (as a consequence, sequitur runs only on Rubies 2.3 or newer).
|
|
3
13
|
- Code restyling to please rubocop 0.7.40.
|
|
4
14
|
|
|
5
15
|
* [CHANGE] Files `Gemfile`, `.travis.yml`, `appveyor.yml` updated.
|
data/LICENSE.txt
CHANGED
data/Rakefile
CHANGED
data/examples/integer_sample.rb
CHANGED
|
@@ -10,9 +10,8 @@ input_sequence = [1, 2, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4, 5]
|
|
|
10
10
|
# Generate the grammar from the sequence
|
|
11
11
|
grammar = Sequitur.build_from(input_sequence)
|
|
12
12
|
|
|
13
|
-
|
|
14
13
|
# Use a formatter to display the grammar rules on the console output
|
|
15
|
-
formatter = Sequitur::Formatter::BaseText.new(
|
|
14
|
+
formatter = Sequitur::Formatter::BaseText.new($stdout)
|
|
16
15
|
|
|
17
16
|
# Now render the rules
|
|
18
17
|
formatter.render(grammar.visitor)
|
data/examples/porridge.rb
CHANGED
|
@@ -3,23 +3,23 @@
|
|
|
3
3
|
require 'sequitur' # Load the Sequitur library
|
|
4
4
|
|
|
5
5
|
# Purpose: demo to show that sequitur gem works on example from sequitur.info website
|
|
6
|
-
input_sequence =
|
|
7
|
-
pease porridge hot,
|
|
8
|
-
pease porridge cold,
|
|
9
|
-
pease porridge in the pot,
|
|
10
|
-
nine days old.
|
|
6
|
+
input_sequence = <<~SNIPPET
|
|
7
|
+
pease porridge hot,
|
|
8
|
+
pease porridge cold,
|
|
9
|
+
pease porridge in the pot,
|
|
10
|
+
nine days old.
|
|
11
11
|
|
|
12
|
-
some like it hot,
|
|
13
|
-
some like it cold,
|
|
14
|
-
some like it in the pot,
|
|
15
|
-
nine days old.
|
|
12
|
+
some like it hot,
|
|
13
|
+
some like it cold,
|
|
14
|
+
some like it in the pot,
|
|
15
|
+
nine days old.
|
|
16
16
|
SNIPPET
|
|
17
17
|
|
|
18
18
|
grammar = Sequitur.build_from(input_sequence)
|
|
19
19
|
|
|
20
20
|
# To display the grammar rules on the console output
|
|
21
21
|
# We use a formatter
|
|
22
|
-
formatter = Sequitur::Formatter::BaseText.new(
|
|
22
|
+
formatter = Sequitur::Formatter::BaseText.new($stdout)
|
|
23
23
|
|
|
24
24
|
# Now render the rules.
|
|
25
25
|
formatter.render(grammar.visitor)
|
data/examples/simple_case.rb
CHANGED
|
@@ -11,7 +11,7 @@ grammar = Sequitur.build_from(input_sequence)
|
|
|
11
11
|
|
|
12
12
|
# To display the grammar rules on the console output
|
|
13
13
|
# We use a formatter
|
|
14
|
-
formatter = Sequitur::Formatter::BaseText.new(
|
|
14
|
+
formatter = Sequitur::Formatter::BaseText.new($stdout)
|
|
15
15
|
|
|
16
16
|
# Now render the rules. Each rule is displayed with the format:
|
|
17
17
|
# rule_id : a_sequence_grammar_symbols.
|
data/examples/symbol_sample.rb
CHANGED
|
@@ -15,7 +15,7 @@ input_sequence = %i[
|
|
|
15
15
|
grammar = Sequitur.build_from(input_sequence)
|
|
16
16
|
|
|
17
17
|
# Use a formatter to display the grammar rules on the console output
|
|
18
|
-
formatter = Sequitur::Formatter::BaseText.new(
|
|
18
|
+
formatter = Sequitur::Formatter::BaseText.new($stdout)
|
|
19
19
|
|
|
20
20
|
# Now render the rules
|
|
21
21
|
formatter.render(grammar.visitor)
|
data/examples/word_sample.rb
CHANGED
|
@@ -7,10 +7,10 @@ require 'sequitur' # Load the Sequitur library
|
|
|
7
7
|
#
|
|
8
8
|
|
|
9
9
|
# Raw input is one String containing repeated sentences...
|
|
10
|
-
raw_input =
|
|
11
|
-
Error: unknown character '?' at position 6
|
|
12
|
-
Error: illegal character '%' at position 20
|
|
13
|
-
Error: unknown character '/' at position 9
|
|
10
|
+
raw_input = <<~SNIPPET
|
|
11
|
+
Error: unknown character '?' at position 6
|
|
12
|
+
Error: illegal character '%' at position 20
|
|
13
|
+
Error: unknown character '/' at position 9
|
|
14
14
|
SNIPPET
|
|
15
15
|
|
|
16
16
|
# Convert into a sequence of words
|
|
@@ -18,9 +18,8 @@ input_sequence = raw_input.scan(/\w+/)
|
|
|
18
18
|
# Generate the grammar from the sequence
|
|
19
19
|
grammar = Sequitur.build_from(input_sequence)
|
|
20
20
|
|
|
21
|
-
|
|
22
21
|
# Use a formatter to display the grammar rules on the console output
|
|
23
|
-
formatter = Sequitur::Formatter::BaseText.new(
|
|
22
|
+
formatter = Sequitur::Formatter::BaseText.new($stdout)
|
|
24
23
|
|
|
25
24
|
# Now render the rules
|
|
26
25
|
formatter.render(grammar.visitor)
|
data/lib/sequitur/constants.rb
CHANGED
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
# Purpose: definition of Sequitur constants.
|
|
5
5
|
|
|
6
6
|
module Sequitur # Module used as a namespace
|
|
7
|
+
# rubocop:disable Naming/ConstantName
|
|
8
|
+
|
|
7
9
|
# The version number of the gem.
|
|
8
|
-
Version = '0.1.
|
|
10
|
+
Version = '0.1.24'
|
|
9
11
|
|
|
10
12
|
# Brief description of the gem.
|
|
11
13
|
Description = 'Ruby implementation of the Sequitur algorithm'
|
|
@@ -20,9 +22,10 @@ module Sequitur # Module used as a namespace
|
|
|
20
22
|
RootDir = begin
|
|
21
23
|
require 'pathname' # Load Pathname class from standard library
|
|
22
24
|
startdir = Pathname(__FILE__).dirname.parent.parent.expand_path
|
|
23
|
-
startdir
|
|
25
|
+
"#{startdir}/" # Append trailing slash character to it
|
|
24
26
|
end
|
|
25
27
|
end
|
|
28
|
+
# rubocop:enable Naming/ConstantName
|
|
26
29
|
end # module
|
|
27
30
|
|
|
28
31
|
# End of file
|
data/lib/sequitur/digram.rb
CHANGED
|
@@ -28,7 +28,7 @@ module Sequitur # Module for classes implementing the Sequitur algorithm
|
|
|
28
28
|
# the sequence symbol1 symbol2 appears.
|
|
29
29
|
def initialize(symbol1, symbol2, aProduction)
|
|
30
30
|
@symbols = [symbol1, symbol2]
|
|
31
|
-
@key = symbol1.hash.to_s(16)
|
|
31
|
+
@key = "#{symbol1.hash.to_s(16)}:#{symbol2.hash.to_s(16)}"
|
|
32
32
|
@production = aProduction
|
|
33
33
|
end
|
|
34
34
|
|
|
@@ -37,13 +37,13 @@ module Sequitur # Module for classes implementing the Sequitur algorithm
|
|
|
37
37
|
# @param other [Digram] another to compare with
|
|
38
38
|
# @return [true/false]
|
|
39
39
|
def ==(other)
|
|
40
|
-
|
|
40
|
+
key == other.key
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
# Does the digram consists of twice the same symbols?
|
|
44
44
|
# @return [true/false] true when symbols.first == symbols.last
|
|
45
45
|
def repeating?
|
|
46
|
-
|
|
46
|
+
symbols[0] == symbols[1]
|
|
47
47
|
end
|
|
48
48
|
end # class
|
|
49
49
|
end # module
|
|
@@ -34,8 +34,7 @@ module Sequitur # Module for classes implementing the Sequitur algorithm
|
|
|
34
34
|
# Each production rule is emitted per line.
|
|
35
35
|
# @return [String]
|
|
36
36
|
def to_string
|
|
37
|
-
|
|
38
|
-
return rule_text
|
|
37
|
+
productions.map(&:to_string).join("\n")
|
|
39
38
|
end
|
|
40
39
|
|
|
41
40
|
# Add a given production to the grammar.
|
|
@@ -55,10 +54,10 @@ module Sequitur # Module for classes implementing the Sequitur algorithm
|
|
|
55
54
|
puts to_string if trace
|
|
56
55
|
prod = productions.delete_at(anIndex)
|
|
57
56
|
# TODO: remove output
|
|
58
|
-
puts(
|
|
57
|
+
puts("Removed: #{prod.to_string}") if trace
|
|
59
58
|
prod.clear_rhs
|
|
60
59
|
|
|
61
|
-
|
|
60
|
+
prod
|
|
62
61
|
end
|
|
63
62
|
|
|
64
63
|
# Add the given token to the grammar.
|
|
@@ -83,7 +82,7 @@ module Sequitur # Module for classes implementing the Sequitur algorithm
|
|
|
83
82
|
# Factory method. Returns a visitor for this grammar.
|
|
84
83
|
# @return [GrammarVisitor]
|
|
85
84
|
def visitor
|
|
86
|
-
|
|
85
|
+
GrammarVisitor.new(self)
|
|
87
86
|
end
|
|
88
87
|
|
|
89
88
|
protected
|
|
@@ -19,7 +19,7 @@ module Sequitur
|
|
|
19
19
|
# and render the visit events in the output stream.
|
|
20
20
|
# @param aGrmOrVisitor [DynamicGrammar or GrammarVisitor]
|
|
21
21
|
def render(aGrmOrVisitor)
|
|
22
|
-
a_visitor = if aGrmOrVisitor.
|
|
22
|
+
a_visitor = if aGrmOrVisitor.is_a?(GrammarVisitor)
|
|
23
23
|
aGrmOrVisitor
|
|
24
24
|
else
|
|
25
25
|
aGrmOrVisitor.visitor
|
|
@@ -12,6 +12,8 @@ module Sequitur
|
|
|
12
12
|
# # Render the grammar (through a visitor)
|
|
13
13
|
# formatter.run(some_grammar.visitor)
|
|
14
14
|
class BaseText < BaseFormatter
|
|
15
|
+
attr_reader :prod_lookup
|
|
16
|
+
|
|
15
17
|
# Constructor.
|
|
16
18
|
# @param anIO [IO] The output stream to which the rendered grammar
|
|
17
19
|
# is written.
|
|
@@ -73,17 +75,11 @@ module Sequitur
|
|
|
73
75
|
|
|
74
76
|
private
|
|
75
77
|
|
|
76
|
-
# Read accessor of the production lookup
|
|
77
|
-
def prod_lookup
|
|
78
|
-
return @prod_lookup
|
|
79
|
-
end
|
|
80
|
-
|
|
81
78
|
# Generate a name of a given production.
|
|
82
79
|
# @param aProduction [Production]
|
|
83
80
|
def prod_name(aProduction)
|
|
84
81
|
prod_index = prod_lookup[aProduction]
|
|
85
|
-
|
|
86
|
-
return name
|
|
82
|
+
prod_index.zero? ? 'start' : "P#{prod_index}"
|
|
87
83
|
end
|
|
88
84
|
end # class
|
|
89
85
|
end # module
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Sequitur # Module for classes implementing the Sequitur algorithm
|
|
4
|
-
# A visitor class dedicated in the visit of Grammar.
|
|
4
|
+
# A visitor class dedicated in the visit of Grammar.
|
|
5
5
|
class GrammarVisitor
|
|
6
6
|
# Link to the grammar to visit
|
|
7
7
|
attr_reader(:grammar)
|