sequitur 0.1.23 → 0.1.25
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 -437
- data/CHANGELOG.md +9 -0
- data/Gemfile +0 -2
- data/LICENSE.txt +1 -1
- data/README.md +2 -3
- data/Rakefile +0 -2
- data/appveyor.yml +10 -10
- data/examples/inductive_english.rb +35 -0
- data/examples/integer_sample.rb +0 -1
- data/examples/porridge.rb +9 -9
- data/examples/word_sample.rb +4 -5
- data/lib/sequitur/constants.rb +7 -4
- data/lib/sequitur/digram.rb +11 -11
- data/lib/sequitur/dynamic_grammar.rb +12 -12
- data/lib/sequitur/formatter/base_formatter.rb +2 -2
- data/lib/sequitur/formatter/base_text.rb +8 -9
- data/lib/sequitur/formatter/debug.rb +10 -4
- data/lib/sequitur/grammar_visitor.rb +7 -7
- data/lib/sequitur/production.rb +203 -205
- data/lib/sequitur/production_ref.rb +18 -20
- data/lib/sequitur/sequitur_grammar.rb +135 -137
- data/lib/sequitur/symbol_sequence.rb +29 -32
- data/lib/sequitur.rb +6 -6
- data/sig/lib/sequitur/constants.rbs +10 -0
- data/sig/lib/sequitur/digram.rbs +37 -0
- data/sig/lib/sequitur/dynamic_grammar.rbs +58 -0
- data/sig/lib/sequitur/formatter/base_formatter.rbs +20 -0
- data/sig/lib/sequitur/formatter/base_text.rbs +62 -0
- data/sig/lib/sequitur/formatter/debug.rbs +89 -0
- data/sig/lib/sequitur/production.rbs +120 -0
- data/sig/lib/sequitur/production_ref.rbs +73 -0
- data/sig/lib/sequitur/sequitur_grammar.rbs +55 -0
- data/sig/lib/sequitur/symbol_sequence.rbs +83 -0
- data/sig/lib/sequitur.rbs +9 -0
- 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 +47 -46
- data/spec/sequitur/symbol_sequence_spec.rb +102 -105
- data/spec/spec_helper.rb +0 -1
- metadata +28 -17
- data/.travis.yml +0 -29
data/lib/sequitur/digram.rb
CHANGED
@@ -9,22 +9,22 @@ module Sequitur # Module for classes implementing the Sequitur algorithm
|
|
9
9
|
# can be a terminal or not.
|
10
10
|
class Digram
|
11
11
|
# The sequence of two consecutive grammar symbols.
|
12
|
-
#
|
12
|
+
# @return [Array<String, Symbol>] The two symbols should respond to the :hash message.
|
13
13
|
attr_reader(:symbols)
|
14
14
|
|
15
|
-
# An unique hash key of the digram
|
15
|
+
# @return [String] An unique hash key of the digram
|
16
16
|
attr_reader(:key)
|
17
17
|
|
18
|
-
# The production in which the digram occurs
|
18
|
+
# @return [Sequitur::Production] The production in which the digram occurs
|
19
19
|
attr_reader(:production)
|
20
20
|
|
21
21
|
# Constructor.
|
22
22
|
# A digram represents a sequence of two symbols
|
23
23
|
# (that appears in a rhs of a production).
|
24
24
|
# Terminal symbols must respond to the :hash message.
|
25
|
-
# @param symbol1 [
|
26
|
-
# @param symbol2 [
|
27
|
-
# @param aProduction [Production] Production in which the RHS
|
25
|
+
# @param symbol1 [String, Symbol] First element of the digram
|
26
|
+
# @param symbol2 [String, Symbol] Second element of the digram
|
27
|
+
# @param aProduction [Sequitur::Production] Production in which the RHS
|
28
28
|
# the sequence symbol1 symbol2 appears.
|
29
29
|
def initialize(symbol1, symbol2, aProduction)
|
30
30
|
@symbols = [symbol1, symbol2]
|
@@ -34,16 +34,16 @@ module Sequitur # Module for classes implementing the Sequitur algorithm
|
|
34
34
|
|
35
35
|
# Equality testing.
|
36
36
|
# true iff keys of both digrams are equal, false otherwise
|
37
|
-
# @param other [Digram] another to compare with
|
38
|
-
# @return [
|
37
|
+
# @param other [Sequitur::Digram] another to compare with
|
38
|
+
# @return [TrueClass, FalseClass]
|
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
|
-
# @return [
|
44
|
+
# @return [TrueClass, FalseClass] 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
|
@@ -13,13 +13,13 @@ module Sequitur # Module for classes implementing the Sequitur algorithm
|
|
13
13
|
# -terminal symbols (i.e. String, Ruby Symbol,...)
|
14
14
|
# -non-terminal symbols (i.e. ProductionRef)
|
15
15
|
class DynamicGrammar
|
16
|
-
# Link to the start production.
|
16
|
+
# @return [Sequitur::Production] Link to the start production.
|
17
17
|
attr_reader(:start)
|
18
18
|
|
19
|
-
# The set of production rules of the grammar
|
19
|
+
# @return [Array<Sequitur::Production>] The set of production rules of the grammar
|
20
20
|
attr_reader(:productions)
|
21
21
|
|
22
|
-
#
|
22
|
+
# @return [TrueClass, FalseClass] Trace the execution of the algorithm.
|
23
23
|
attr_accessor(:trace)
|
24
24
|
|
25
25
|
# Constructor.
|
@@ -34,12 +34,12 @@ 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.
|
42
|
-
# @param aProduction [Production]
|
41
|
+
# @param aProduction [Sequitur::Production]
|
42
|
+
# @return [Array<Sequitur::Production>]
|
43
43
|
def add_production(aProduction)
|
44
44
|
# TODO: remove output
|
45
45
|
puts "Adding #{aProduction.object_id}" if trace
|
@@ -48,8 +48,8 @@ module Sequitur # Module for classes implementing the Sequitur algorithm
|
|
48
48
|
end
|
49
49
|
|
50
50
|
# Remove a production with given index from the grammar
|
51
|
-
# @param anIndex [
|
52
|
-
# @return [Production] the production removed from the grammar.
|
51
|
+
# @param anIndex [Integer]
|
52
|
+
# @return [Sequitur::Production] the production removed from the grammar.
|
53
53
|
def remove_production(anIndex)
|
54
54
|
puts "Before production removal #{productions[anIndex].object_id}" if trace
|
55
55
|
puts to_string if trace
|
@@ -58,7 +58,7 @@ module Sequitur # Module for classes implementing the Sequitur algorithm
|
|
58
58
|
puts("Removed: #{prod.to_string}") if trace
|
59
59
|
prod.clear_rhs
|
60
60
|
|
61
|
-
|
61
|
+
prod
|
62
62
|
end
|
63
63
|
|
64
64
|
# Add the given token to the grammar.
|
@@ -70,7 +70,7 @@ module Sequitur # Module for classes implementing the Sequitur algorithm
|
|
70
70
|
|
71
71
|
# Part of the 'visitee' role in the Visitor design pattern.
|
72
72
|
# A visitee is expected to accept the visit from a visitor object
|
73
|
-
# @param aVisitor [GrammarVisitor] the visitor object
|
73
|
+
# @param aVisitor [Sequitur::GrammarVisitor] the visitor object
|
74
74
|
def accept(aVisitor)
|
75
75
|
aVisitor.start_visit_grammar(self)
|
76
76
|
|
@@ -81,9 +81,9 @@ module Sequitur # Module for classes implementing the Sequitur algorithm
|
|
81
81
|
end
|
82
82
|
|
83
83
|
# Factory method. Returns a visitor for this grammar.
|
84
|
-
# @return [GrammarVisitor]
|
84
|
+
# @return [Sequitur::GrammarVisitor]
|
85
85
|
def visitor
|
86
|
-
|
86
|
+
GrammarVisitor.new(self)
|
87
87
|
end
|
88
88
|
|
89
89
|
protected
|
@@ -17,9 +17,9 @@ module Sequitur
|
|
17
17
|
|
18
18
|
# Given a grammar or a grammar visitor, perform the visit
|
19
19
|
# and render the visit events in the output stream.
|
20
|
-
# @param aGrmOrVisitor [DynamicGrammar
|
20
|
+
# @param aGrmOrVisitor [DynamicGrammar, 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,9 @@ module Sequitur
|
|
12
12
|
# # Render the grammar (through a visitor)
|
13
13
|
# formatter.run(some_grammar.visitor)
|
14
14
|
class BaseText < BaseFormatter
|
15
|
+
# @return [Hash{Production => Integer}]
|
16
|
+
attr_reader :prod_lookup
|
17
|
+
|
15
18
|
# Constructor.
|
16
19
|
# @param anIO [IO] The output stream to which the rendered grammar
|
17
20
|
# is written.
|
@@ -22,7 +25,7 @@ module Sequitur
|
|
22
25
|
|
23
26
|
# Method called by a GrammarVisitor to which the formatter subscribed.
|
24
27
|
# Notification of a visit event: the visitor is about to visit a grammar
|
25
|
-
# @param aGrammar [DynamicGrammar
|
28
|
+
# @param aGrammar [DynamicGrammar]
|
26
29
|
def before_grammar(aGrammar)
|
27
30
|
aGrammar.productions.each_with_index do |a_prod, index|
|
28
31
|
prod_lookup[a_prod] = index
|
@@ -32,7 +35,7 @@ module Sequitur
|
|
32
35
|
# Method called by a GrammarVisitor to which the formatter subscribed.
|
33
36
|
# Notification of a visit event: the visitor is about to visit
|
34
37
|
# a production
|
35
|
-
# @param aProduction [
|
38
|
+
# @param aProduction [Production]
|
36
39
|
def before_production(aProduction)
|
37
40
|
p_name = prod_name(aProduction)
|
38
41
|
output.print p_name
|
@@ -67,23 +70,19 @@ module Sequitur
|
|
67
70
|
# Method called by a GrammarVisitor to which the formatter subscribed.
|
68
71
|
# Notification of a visit event: the visitor complete the visit
|
69
72
|
# of a production
|
73
|
+
# @param _ [Production]
|
70
74
|
def after_production(_)
|
71
75
|
output.print ".\n"
|
72
76
|
end
|
73
77
|
|
74
78
|
private
|
75
79
|
|
76
|
-
# Read accessor of the production lookup
|
77
|
-
def prod_lookup
|
78
|
-
return @prod_lookup
|
79
|
-
end
|
80
|
-
|
81
80
|
# Generate a name of a given production.
|
82
81
|
# @param aProduction [Production]
|
82
|
+
# @return [String]
|
83
83
|
def prod_name(aProduction)
|
84
84
|
prod_index = prod_lookup[aProduction]
|
85
|
-
|
86
|
-
return name
|
85
|
+
prod_index.zero? ? 'start' : "P#{prod_index}"
|
87
86
|
end
|
88
87
|
end # class
|
89
88
|
end # module
|
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
require_relative 'base_formatter'
|
4
4
|
|
5
|
-
|
6
5
|
module Sequitur
|
7
6
|
module Formatter
|
8
7
|
# A formatter class that can render the notification events
|
@@ -14,7 +13,7 @@ module Sequitur
|
|
14
13
|
# # Render the visit notifications
|
15
14
|
# formatter.run(some_grammar.visitor)
|
16
15
|
class Debug < BaseFormatter
|
17
|
-
# Current indentation level
|
16
|
+
# @return [Integer] Current indentation level
|
18
17
|
attr_accessor(:indentation)
|
19
18
|
|
20
19
|
# Constructor.
|
@@ -27,7 +26,7 @@ module Sequitur
|
|
27
26
|
|
28
27
|
# Method called by a GrammarVisitor to which the formatter subscribed.
|
29
28
|
# Notification of a visit event: the visitor is about to visit a grammar
|
30
|
-
# @param _ [DynamicGrammar
|
29
|
+
# @param _ [DynamicGrammar]
|
31
30
|
def before_grammar(_)
|
32
31
|
output_event(__method__, indentation)
|
33
32
|
indent
|
@@ -36,7 +35,7 @@ module Sequitur
|
|
36
35
|
# Method called by a GrammarVisitor to which the formatter subscribed.
|
37
36
|
# Notification of a visit event: the visitor is about to visit
|
38
37
|
# a production
|
39
|
-
# @param _ [
|
38
|
+
# @param _ [Production]
|
40
39
|
def before_production(_)
|
41
40
|
output_event(__method__, indentation)
|
42
41
|
indent
|
@@ -96,6 +95,7 @@ module Sequitur
|
|
96
95
|
# Method called by a GrammarVisitor to which the formatter subscribed.
|
97
96
|
# Notification of a visit event: the visitor completed the visit
|
98
97
|
# of a production
|
98
|
+
# @param _ [Production]
|
99
99
|
def after_production(_)
|
100
100
|
dedent
|
101
101
|
output_event(__method__, indentation)
|
@@ -104,6 +104,7 @@ module Sequitur
|
|
104
104
|
# Method called by a GrammarVisitor to which the formatter subscribed.
|
105
105
|
# Notification of a visit event: the visitor completed the visit
|
106
106
|
# of a grammar
|
107
|
+
# @param _ [DynamicGrammar]
|
107
108
|
def after_grammar(_)
|
108
109
|
dedent
|
109
110
|
output_event(__method__, indentation)
|
@@ -111,14 +112,19 @@ module Sequitur
|
|
111
112
|
|
112
113
|
private
|
113
114
|
|
115
|
+
# @return [Integer]
|
114
116
|
def indent
|
115
117
|
@indentation += 1
|
116
118
|
end
|
117
119
|
|
120
|
+
# @return [Integer]
|
118
121
|
def dedent
|
119
122
|
@indentation -= 1
|
120
123
|
end
|
121
124
|
|
125
|
+
# @param anEvent [Symbol]
|
126
|
+
# @param indentationLevel [Integer]
|
127
|
+
# @return [NilClass]
|
122
128
|
def output_event(anEvent, indentationLevel)
|
123
129
|
output.puts "#{' ' * 2 * indentationLevel}#{anEvent}"
|
124
130
|
end
|
@@ -1,16 +1,16 @@
|
|
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
|
-
# Link to the grammar to visit
|
6
|
+
# @return [Sequitur::DynamicGrammar] Link to the grammar to visit
|
7
7
|
attr_reader(:grammar)
|
8
8
|
|
9
|
-
# List of objects that subscribed to the visit event notification.
|
9
|
+
# @return [Object] List of objects that subscribed to the visit event notification.
|
10
10
|
attr_reader(:subscribers)
|
11
11
|
|
12
12
|
# Build a visitor for the given grammar.
|
13
|
-
# @param aGrammar [DynamicGrammar
|
13
|
+
# @param aGrammar [DynamicGrammar] the grammar to visit.
|
14
14
|
def initialize(aGrammar)
|
15
15
|
@grammar = aGrammar
|
16
16
|
@subscribers = []
|
@@ -35,13 +35,13 @@ module Sequitur # Module for classes implementing the Sequitur algorithm
|
|
35
35
|
end
|
36
36
|
|
37
37
|
# Visit event. The visitor is about to visit the grammar.
|
38
|
-
# @param aGrammar [DynamicGrammar
|
38
|
+
# @param aGrammar [DynamicGrammar] the grammar to visit.
|
39
39
|
def start_visit_grammar(aGrammar)
|
40
40
|
broadcast(:before_grammar, aGrammar)
|
41
41
|
end
|
42
42
|
|
43
43
|
# Visit event. The visitor is about to visit the given production.
|
44
|
-
# @param aProduction [Production] the production to visit.
|
44
|
+
# @param aProduction [Sequitur::Production] the production to visit.
|
45
45
|
def start_visit_production(aProduction)
|
46
46
|
broadcast(:before_production, aProduction)
|
47
47
|
end
|
@@ -82,7 +82,7 @@ module Sequitur # Module for classes implementing the Sequitur algorithm
|
|
82
82
|
end
|
83
83
|
|
84
84
|
# Visit event. The visitor has completed the visit of the grammar.
|
85
|
-
# @param aGrammar [DynamicGrammar
|
85
|
+
# @param aGrammar [DynamicGrammar] the grammar to visit.
|
86
86
|
def end_visit_grammar(aGrammar)
|
87
87
|
broadcast(:after_grammar, aGrammar)
|
88
88
|
end
|