sequitur 0.1.10 → 0.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 +8 -8
- data/CHANGELOG.md +4 -0
- data/README.md +58 -1
- data/Rakefile +31 -31
- data/examples/integer_sample.rb +33 -0
- data/examples/porridge.rb +41 -0
- data/examples/simple_case.rb +27 -0
- data/examples/symbol_sample.rb +28 -0
- data/examples/word_sample.rb +30 -0
- data/lib/sequitur.rb +1 -1
- data/lib/sequitur/constants.rb +1 -1
- data/lib/sequitur/digram.rb +52 -52
- data/lib/sequitur/dynamic_grammar.rb +106 -106
- data/lib/sequitur/formatter/base_formatter.rb +39 -39
- data/lib/sequitur/formatter/base_text.rb +95 -95
- data/lib/sequitur/formatter/debug.rb +131 -131
- data/lib/sequitur/grammar_visitor.rb +110 -110
- data/lib/sequitur/production.rb +243 -243
- data/lib/sequitur/production_ref.rb +119 -119
- data/lib/sequitur/sequitur_grammar.rb +158 -158
- data/lib/sequitur/symbol_sequence.rb +182 -182
- data/spec/sequitur/sequitur_grammar_spec.rb +75 -3
- metadata +7 -2
@@ -1,131 +1,131 @@
|
|
1
|
-
require_relative 'base_formatter'
|
2
|
-
|
3
|
-
|
4
|
-
module Sequitur
|
5
|
-
module Formatter
|
6
|
-
|
7
|
-
# A formatter class that can render the notification events
|
8
|
-
# from a grammar visitor
|
9
|
-
# @example
|
10
|
-
# some_grammar = ... # Points to a DynamicGrammar-like object
|
11
|
-
# # Output the result to the standard console output
|
12
|
-
# formatter = Sequitur::Formatter::Debug.new(STDOUT)
|
13
|
-
# # Render the visit notifications
|
14
|
-
# formatter.run(some_grammar.visitor)
|
15
|
-
class Debug < BaseFormatter
|
16
|
-
# Current indentation level
|
17
|
-
attr(:indentation)
|
18
|
-
|
19
|
-
# Constructor.
|
20
|
-
# @param anIO [IO] The output stream to which the rendered grammar
|
21
|
-
# is written.
|
22
|
-
def initialize(anIO)
|
23
|
-
super(anIO)
|
24
|
-
@indentation = 0
|
25
|
-
end
|
26
|
-
|
27
|
-
public
|
28
|
-
|
29
|
-
# Method called by a GrammarVisitor to which the formatter subscribed.
|
30
|
-
# Notification of a visit event: the visitor is about to visit a grammar
|
31
|
-
# @param _ [DynamicGrammar-like object]
|
32
|
-
def before_grammar(_)
|
33
|
-
output_event(__method__, indentation)
|
34
|
-
indent
|
35
|
-
end
|
36
|
-
|
37
|
-
# Method called by a GrammarVisitor to which the formatter subscribed.
|
38
|
-
# Notification of a visit event: the visitor is about to visit
|
39
|
-
# a production
|
40
|
-
# @param _ [aProduction]
|
41
|
-
def before_production(_)
|
42
|
-
output_event(__method__, indentation)
|
43
|
-
indent
|
44
|
-
end
|
45
|
-
|
46
|
-
# Method called by a GrammarVisitor to which the formatter subscribed.
|
47
|
-
# Notification of a visit event: the visitor is about to visit
|
48
|
-
# the rhs of a production
|
49
|
-
# @param _ [Array]
|
50
|
-
def before_rhs(_)
|
51
|
-
output_event(__method__, indentation)
|
52
|
-
indent
|
53
|
-
end
|
54
|
-
|
55
|
-
# Method called by a GrammarVisitor to which the formatter subscribed.
|
56
|
-
# Notification of a visit event: the visitor is about to visit
|
57
|
-
# a terminal symbol from the rhs of a production
|
58
|
-
# @param _ [Object]
|
59
|
-
def before_terminal(_)
|
60
|
-
output_event(__method__, indentation)
|
61
|
-
end
|
62
|
-
|
63
|
-
# Method called by a GrammarVisitor to which the formatter subscribed.
|
64
|
-
# Notification of a visit event: the visitor completed the visit of
|
65
|
-
# a terminal symbol from the rhs of a production
|
66
|
-
# @param _ [Object]
|
67
|
-
def after_terminal(_)
|
68
|
-
output_event(__method__, indentation)
|
69
|
-
end
|
70
|
-
|
71
|
-
# Method called by a GrammarVisitor to which the formatter subscribed.
|
72
|
-
# Notification of a visit event: the visitor is about to visit
|
73
|
-
# a non-terminal (= an allusion to a production) in the rhs of a
|
74
|
-
# production
|
75
|
-
# @param _ [Production] a production occurring in the rhs
|
76
|
-
def before_non_terminal(_)
|
77
|
-
output_event(__method__, indentation)
|
78
|
-
end
|
79
|
-
|
80
|
-
# Method called by a GrammarVisitor to which the formatter subscribed.
|
81
|
-
# Notification of a visit event: the visitor completed the visit of
|
82
|
-
# a non-terminal symbol from the rhs of a production.
|
83
|
-
# @param _ [Object]
|
84
|
-
def after_non_terminal(_)
|
85
|
-
output_event(__method__, indentation)
|
86
|
-
end
|
87
|
-
|
88
|
-
# Method called by a GrammarVisitor to which the formatter subscribed.
|
89
|
-
# Notification of a visit event: the visitor completed the visit of
|
90
|
-
# the rhs of a production
|
91
|
-
# @param _ [Array]
|
92
|
-
def after_rhs(_)
|
93
|
-
dedent
|
94
|
-
output_event(__method__, indentation)
|
95
|
-
end
|
96
|
-
|
97
|
-
# Method called by a GrammarVisitor to which the formatter subscribed.
|
98
|
-
# Notification of a visit event: the visitor completed the visit
|
99
|
-
# of a production
|
100
|
-
def after_production(_)
|
101
|
-
dedent
|
102
|
-
output_event(__method__, indentation)
|
103
|
-
end
|
104
|
-
|
105
|
-
# Method called by a GrammarVisitor to which the formatter subscribed.
|
106
|
-
# Notification of a visit event: the visitor completed the visit
|
107
|
-
# of a grammar
|
108
|
-
def after_grammar(_)
|
109
|
-
dedent
|
110
|
-
output_event(__method__, indentation)
|
111
|
-
end
|
112
|
-
|
113
|
-
private
|
114
|
-
|
115
|
-
def indent()
|
116
|
-
@indentation += 1
|
117
|
-
end
|
118
|
-
|
119
|
-
def dedent()
|
120
|
-
@indentation -= 1
|
121
|
-
end
|
122
|
-
|
123
|
-
def output_event(anEvent, indentationLevel)
|
124
|
-
output.puts "#{' ' * 2 * indentationLevel}#{anEvent}"
|
125
|
-
end
|
126
|
-
|
127
|
-
end # class
|
128
|
-
end # module
|
129
|
-
end # module
|
130
|
-
|
131
|
-
# End of file
|
1
|
+
require_relative 'base_formatter'
|
2
|
+
|
3
|
+
|
4
|
+
module Sequitur
|
5
|
+
module Formatter
|
6
|
+
|
7
|
+
# A formatter class that can render the notification events
|
8
|
+
# from a grammar visitor
|
9
|
+
# @example
|
10
|
+
# some_grammar = ... # Points to a DynamicGrammar-like object
|
11
|
+
# # Output the result to the standard console output
|
12
|
+
# formatter = Sequitur::Formatter::Debug.new(STDOUT)
|
13
|
+
# # Render the visit notifications
|
14
|
+
# formatter.run(some_grammar.visitor)
|
15
|
+
class Debug < BaseFormatter
|
16
|
+
# Current indentation level
|
17
|
+
attr(:indentation)
|
18
|
+
|
19
|
+
# Constructor.
|
20
|
+
# @param anIO [IO] The output stream to which the rendered grammar
|
21
|
+
# is written.
|
22
|
+
def initialize(anIO)
|
23
|
+
super(anIO)
|
24
|
+
@indentation = 0
|
25
|
+
end
|
26
|
+
|
27
|
+
public
|
28
|
+
|
29
|
+
# Method called by a GrammarVisitor to which the formatter subscribed.
|
30
|
+
# Notification of a visit event: the visitor is about to visit a grammar
|
31
|
+
# @param _ [DynamicGrammar-like object]
|
32
|
+
def before_grammar(_)
|
33
|
+
output_event(__method__, indentation)
|
34
|
+
indent
|
35
|
+
end
|
36
|
+
|
37
|
+
# Method called by a GrammarVisitor to which the formatter subscribed.
|
38
|
+
# Notification of a visit event: the visitor is about to visit
|
39
|
+
# a production
|
40
|
+
# @param _ [aProduction]
|
41
|
+
def before_production(_)
|
42
|
+
output_event(__method__, indentation)
|
43
|
+
indent
|
44
|
+
end
|
45
|
+
|
46
|
+
# Method called by a GrammarVisitor to which the formatter subscribed.
|
47
|
+
# Notification of a visit event: the visitor is about to visit
|
48
|
+
# the rhs of a production
|
49
|
+
# @param _ [Array]
|
50
|
+
def before_rhs(_)
|
51
|
+
output_event(__method__, indentation)
|
52
|
+
indent
|
53
|
+
end
|
54
|
+
|
55
|
+
# Method called by a GrammarVisitor to which the formatter subscribed.
|
56
|
+
# Notification of a visit event: the visitor is about to visit
|
57
|
+
# a terminal symbol from the rhs of a production
|
58
|
+
# @param _ [Object]
|
59
|
+
def before_terminal(_)
|
60
|
+
output_event(__method__, indentation)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Method called by a GrammarVisitor to which the formatter subscribed.
|
64
|
+
# Notification of a visit event: the visitor completed the visit of
|
65
|
+
# a terminal symbol from the rhs of a production
|
66
|
+
# @param _ [Object]
|
67
|
+
def after_terminal(_)
|
68
|
+
output_event(__method__, indentation)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Method called by a GrammarVisitor to which the formatter subscribed.
|
72
|
+
# Notification of a visit event: the visitor is about to visit
|
73
|
+
# a non-terminal (= an allusion to a production) in the rhs of a
|
74
|
+
# production
|
75
|
+
# @param _ [Production] a production occurring in the rhs
|
76
|
+
def before_non_terminal(_)
|
77
|
+
output_event(__method__, indentation)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Method called by a GrammarVisitor to which the formatter subscribed.
|
81
|
+
# Notification of a visit event: the visitor completed the visit of
|
82
|
+
# a non-terminal symbol from the rhs of a production.
|
83
|
+
# @param _ [Object]
|
84
|
+
def after_non_terminal(_)
|
85
|
+
output_event(__method__, indentation)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Method called by a GrammarVisitor to which the formatter subscribed.
|
89
|
+
# Notification of a visit event: the visitor completed the visit of
|
90
|
+
# the rhs of a production
|
91
|
+
# @param _ [Array]
|
92
|
+
def after_rhs(_)
|
93
|
+
dedent
|
94
|
+
output_event(__method__, indentation)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Method called by a GrammarVisitor to which the formatter subscribed.
|
98
|
+
# Notification of a visit event: the visitor completed the visit
|
99
|
+
# of a production
|
100
|
+
def after_production(_)
|
101
|
+
dedent
|
102
|
+
output_event(__method__, indentation)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Method called by a GrammarVisitor to which the formatter subscribed.
|
106
|
+
# Notification of a visit event: the visitor completed the visit
|
107
|
+
# of a grammar
|
108
|
+
def after_grammar(_)
|
109
|
+
dedent
|
110
|
+
output_event(__method__, indentation)
|
111
|
+
end
|
112
|
+
|
113
|
+
private
|
114
|
+
|
115
|
+
def indent()
|
116
|
+
@indentation += 1
|
117
|
+
end
|
118
|
+
|
119
|
+
def dedent()
|
120
|
+
@indentation -= 1
|
121
|
+
end
|
122
|
+
|
123
|
+
def output_event(anEvent, indentationLevel)
|
124
|
+
output.puts "#{' ' * 2 * indentationLevel}#{anEvent}"
|
125
|
+
end
|
126
|
+
|
127
|
+
end # class
|
128
|
+
end # module
|
129
|
+
end # module
|
130
|
+
|
131
|
+
# End of file
|
@@ -1,110 +1,110 @@
|
|
1
|
-
module Sequitur # Module for classes implementing the Sequitur algorithm
|
2
|
-
|
3
|
-
# A visitor class dedicated in the visit of Grammar.
|
4
|
-
class GrammarVisitor
|
5
|
-
# Link to the grammar to visit
|
6
|
-
attr_reader(:grammar)
|
7
|
-
|
8
|
-
# List of objects that subscribed to the visit event notification.
|
9
|
-
attr_reader(:subscribers)
|
10
|
-
|
11
|
-
# Build a visitor for the given grammar.
|
12
|
-
# @param aGrammar [DynamicGrammar-like] the grammar to visit.
|
13
|
-
def initialize(aGrammar)
|
14
|
-
@grammar = aGrammar
|
15
|
-
@subscribers = []
|
16
|
-
end
|
17
|
-
|
18
|
-
public
|
19
|
-
|
20
|
-
# Add a subscriber for the visit event notification.
|
21
|
-
# @param aSubscriber [Object]
|
22
|
-
def subscribe(aSubscriber)
|
23
|
-
subscribers << aSubscriber
|
24
|
-
end
|
25
|
-
|
26
|
-
# Remove the given object from the subscription list.
|
27
|
-
# The object won't be notified of visit events.
|
28
|
-
# @param aSubscriber [Object]
|
29
|
-
def unsubscribe(aSubscriber)
|
30
|
-
subscribers.delete_if { |entry| entry == aSubscriber }
|
31
|
-
end
|
32
|
-
|
33
|
-
# The signal to start the visit.
|
34
|
-
def start()
|
35
|
-
grammar.accept(self)
|
36
|
-
end
|
37
|
-
|
38
|
-
|
39
|
-
# Visit event. The visitor is about to visit the grammar.
|
40
|
-
# @param aGrammar [DynamicGrammar-like] the grammar to visit.
|
41
|
-
def start_visit_grammar(aGrammar)
|
42
|
-
broadcast(:before_grammar, aGrammar)
|
43
|
-
end
|
44
|
-
|
45
|
-
|
46
|
-
# Visit event. The visitor is about to visit the given production.
|
47
|
-
# @param aProduction [Production] the production to visit.
|
48
|
-
def start_visit_production(aProduction)
|
49
|
-
broadcast(:before_production, aProduction)
|
50
|
-
end
|
51
|
-
|
52
|
-
# Visit event. The visitor is about to visit the given rhs of production.
|
53
|
-
# @param rhs [SymbolSequence] the rhs of a production to visit.
|
54
|
-
def start_visit_rhs(rhs)
|
55
|
-
broadcast(:before_rhs, rhs)
|
56
|
-
end
|
57
|
-
|
58
|
-
# Visit event. The visitor is visiting the
|
59
|
-
# given reference production (= non-terminal symbol).
|
60
|
-
# @param aProdRef [ProductionRef] the production reference to visit.
|
61
|
-
def visit_prod_ref(aProdRef)
|
62
|
-
production = aProdRef.production
|
63
|
-
broadcast(:before_non_terminal, production)
|
64
|
-
broadcast(:after_non_terminal, production)
|
65
|
-
end
|
66
|
-
|
67
|
-
# Visit event. The visitor is visiting the
|
68
|
-
# given terminal symbol.
|
69
|
-
# @param aTerminal [Object] the terminal to visit.
|
70
|
-
def visit_terminal(aTerminal)
|
71
|
-
broadcast(:before_terminal, aTerminal)
|
72
|
-
broadcast(:after_terminal, aTerminal)
|
73
|
-
end
|
74
|
-
|
75
|
-
# Visit event. The visitor has completed its visit of the given rhs.
|
76
|
-
# @param rhs [SymbolSequence] the rhs of a production to visit.
|
77
|
-
def end_visit_rhs(rhs)
|
78
|
-
broadcast(:after_rhs, rhs)
|
79
|
-
end
|
80
|
-
|
81
|
-
# Visit event. The visitor has completed its visit of the given production.
|
82
|
-
# @param aProduction [Production] the production to visit.
|
83
|
-
def end_visit_production(aProduction)
|
84
|
-
broadcast(:after_production, aProduction)
|
85
|
-
end
|
86
|
-
|
87
|
-
# Visit event. The visitor has completed the visit of the grammar.
|
88
|
-
# @param aGrammar [DynamicGrammar-like] the grammar to visit.
|
89
|
-
def end_visit_grammar(aGrammar)
|
90
|
-
broadcast(:after_grammar, aGrammar)
|
91
|
-
end
|
92
|
-
|
93
|
-
private
|
94
|
-
|
95
|
-
# Send a notification to all subscribers.
|
96
|
-
# @param msg [Symbol] event to notify
|
97
|
-
# @param args [Array] arguments of the notification.
|
98
|
-
def broadcast(msg, *args)
|
99
|
-
subscribers.each do |a_subscriber|
|
100
|
-
next unless a_subscriber.respond_to?(msg)
|
101
|
-
a_subscriber.send(msg, *args)
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
|
106
|
-
end # class
|
107
|
-
|
108
|
-
end # module
|
109
|
-
|
110
|
-
# End of file
|
1
|
+
module Sequitur # Module for classes implementing the Sequitur algorithm
|
2
|
+
|
3
|
+
# A visitor class dedicated in the visit of Grammar.
|
4
|
+
class GrammarVisitor
|
5
|
+
# Link to the grammar to visit
|
6
|
+
attr_reader(:grammar)
|
7
|
+
|
8
|
+
# List of objects that subscribed to the visit event notification.
|
9
|
+
attr_reader(:subscribers)
|
10
|
+
|
11
|
+
# Build a visitor for the given grammar.
|
12
|
+
# @param aGrammar [DynamicGrammar-like] the grammar to visit.
|
13
|
+
def initialize(aGrammar)
|
14
|
+
@grammar = aGrammar
|
15
|
+
@subscribers = []
|
16
|
+
end
|
17
|
+
|
18
|
+
public
|
19
|
+
|
20
|
+
# Add a subscriber for the visit event notification.
|
21
|
+
# @param aSubscriber [Object]
|
22
|
+
def subscribe(aSubscriber)
|
23
|
+
subscribers << aSubscriber
|
24
|
+
end
|
25
|
+
|
26
|
+
# Remove the given object from the subscription list.
|
27
|
+
# The object won't be notified of visit events.
|
28
|
+
# @param aSubscriber [Object]
|
29
|
+
def unsubscribe(aSubscriber)
|
30
|
+
subscribers.delete_if { |entry| entry == aSubscriber }
|
31
|
+
end
|
32
|
+
|
33
|
+
# The signal to start the visit.
|
34
|
+
def start()
|
35
|
+
grammar.accept(self)
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
# Visit event. The visitor is about to visit the grammar.
|
40
|
+
# @param aGrammar [DynamicGrammar-like] the grammar to visit.
|
41
|
+
def start_visit_grammar(aGrammar)
|
42
|
+
broadcast(:before_grammar, aGrammar)
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
# Visit event. The visitor is about to visit the given production.
|
47
|
+
# @param aProduction [Production] the production to visit.
|
48
|
+
def start_visit_production(aProduction)
|
49
|
+
broadcast(:before_production, aProduction)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Visit event. The visitor is about to visit the given rhs of production.
|
53
|
+
# @param rhs [SymbolSequence] the rhs of a production to visit.
|
54
|
+
def start_visit_rhs(rhs)
|
55
|
+
broadcast(:before_rhs, rhs)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Visit event. The visitor is visiting the
|
59
|
+
# given reference production (= non-terminal symbol).
|
60
|
+
# @param aProdRef [ProductionRef] the production reference to visit.
|
61
|
+
def visit_prod_ref(aProdRef)
|
62
|
+
production = aProdRef.production
|
63
|
+
broadcast(:before_non_terminal, production)
|
64
|
+
broadcast(:after_non_terminal, production)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Visit event. The visitor is visiting the
|
68
|
+
# given terminal symbol.
|
69
|
+
# @param aTerminal [Object] the terminal to visit.
|
70
|
+
def visit_terminal(aTerminal)
|
71
|
+
broadcast(:before_terminal, aTerminal)
|
72
|
+
broadcast(:after_terminal, aTerminal)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Visit event. The visitor has completed its visit of the given rhs.
|
76
|
+
# @param rhs [SymbolSequence] the rhs of a production to visit.
|
77
|
+
def end_visit_rhs(rhs)
|
78
|
+
broadcast(:after_rhs, rhs)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Visit event. The visitor has completed its visit of the given production.
|
82
|
+
# @param aProduction [Production] the production to visit.
|
83
|
+
def end_visit_production(aProduction)
|
84
|
+
broadcast(:after_production, aProduction)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Visit event. The visitor has completed the visit of the grammar.
|
88
|
+
# @param aGrammar [DynamicGrammar-like] the grammar to visit.
|
89
|
+
def end_visit_grammar(aGrammar)
|
90
|
+
broadcast(:after_grammar, aGrammar)
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
# Send a notification to all subscribers.
|
96
|
+
# @param msg [Symbol] event to notify
|
97
|
+
# @param args [Array] arguments of the notification.
|
98
|
+
def broadcast(msg, *args)
|
99
|
+
subscribers.each do |a_subscriber|
|
100
|
+
next unless a_subscriber.respond_to?(msg)
|
101
|
+
a_subscriber.send(msg, *args)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
end # class
|
107
|
+
|
108
|
+
end # module
|
109
|
+
|
110
|
+
# End of file
|