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.
@@ -1,106 +1,106 @@
1
- require_relative 'production'
2
- require_relative 'grammar_visitor'
3
-
4
- module Sequitur # Module for classes implementing the Sequitur algorithm
5
-
6
- # A dynamic grammar is a context-free grammar that can be built incrementally.
7
- # Formally, a grammar has:
8
- # One start production
9
- # Zero or more other productions
10
- # Each production has a rhs that is a sequence of grammar symbols.
11
- # Grammar symbols are categorized into
12
- # -terminal symbols (i.e. String, Ruby Symbol,...)
13
- # -non-terminal symbols (i.e. ProductionRef)
14
- class DynamicGrammar
15
- # Link to the start production.
16
- attr_reader(:start)
17
-
18
- # The set of production rules of the grammar
19
- attr_reader(:productions)
20
-
21
- # nodoc Trace the execution of the algorithm.
22
- attr(:trace)
23
-
24
-
25
- # Constructor.
26
- # Build a grammar with one empty rule as start/start rule.
27
- def initialize()
28
- @start = Production.new
29
- @productions = [ start ]
30
- @trace = false
31
- end
32
-
33
- public
34
-
35
- # Emit a text representation of the grammar.
36
- # Each production rule is emitted per line.
37
- # @return [String]
38
- def to_string()
39
- rule_text = productions.map(&:to_string).join("\n")
40
- return rule_text
41
- end
42
-
43
-
44
- # Add a given production to the grammar.
45
- # @param aProduction [Production]
46
- def add_production(aProduction)
47
- # TODO: remove output
48
- puts "Adding #{aProduction.object_id}" if trace
49
- puts aProduction.to_string if trace
50
- productions << aProduction
51
- end
52
-
53
-
54
- # Remove a production with given index from the grammar
55
- # @param anIndex [Fixnum]
56
- # @return [Production] the production removed from the grammar.
57
- def remove_production(anIndex)
58
- puts "Before production removal #{productions[anIndex].object_id}" if trace
59
- puts to_string if trace
60
- prod = productions.delete_at(anIndex)
61
- # TODO: remove output
62
- puts('Removed: ' + prod.to_string) if trace
63
- prod.clear_rhs
64
-
65
- return prod
66
- end
67
-
68
-
69
- # Add the given token to the grammar.
70
- # Append the token to the rhs of the start/start rule.
71
- # @param aToken [Object] input token to add
72
- def add_token(aToken)
73
- append_symbol_to(start, aToken)
74
- end
75
-
76
- # Part of the 'visitee' role in the Visitor design pattern.
77
- # A visitee is expected to accept the visit from a visitor object
78
- # @param aVisitor [GrammarVisitor] the visitor object
79
- def accept(aVisitor)
80
- aVisitor.start_visit_grammar(self)
81
-
82
- # Let's proceed with the visit of productions
83
- productions.each { |prod| prod.accept(aVisitor) }
84
-
85
- aVisitor.end_visit_grammar(self)
86
- end
87
-
88
- # Factory method. Returns a visitor for this grammar.
89
- # @return [GrammarVisitor]
90
- def visitor()
91
- return GrammarVisitor.new(self)
92
- end
93
-
94
- protected
95
-
96
- # Append a given symbol to the rhs of passed production.
97
- # @param aProduction [Production]
98
- # @param aSymbol [Object]
99
- def append_symbol_to(aProduction, aSymbol)
100
- aProduction.append_symbol(aSymbol)
101
- end
102
- end # class
103
-
104
- end # module
105
-
106
- # End of file
1
+ require_relative 'production'
2
+ require_relative 'grammar_visitor'
3
+
4
+ module Sequitur # Module for classes implementing the Sequitur algorithm
5
+
6
+ # A dynamic grammar is a context-free grammar that can be built incrementally.
7
+ # Formally, a grammar has:
8
+ # One start production
9
+ # Zero or more other productions
10
+ # Each production has a rhs that is a sequence of grammar symbols.
11
+ # Grammar symbols are categorized into
12
+ # -terminal symbols (i.e. String, Ruby Symbol,...)
13
+ # -non-terminal symbols (i.e. ProductionRef)
14
+ class DynamicGrammar
15
+ # Link to the start production.
16
+ attr_reader(:start)
17
+
18
+ # The set of production rules of the grammar
19
+ attr_reader(:productions)
20
+
21
+ # nodoc Trace the execution of the algorithm.
22
+ attr(:trace)
23
+
24
+
25
+ # Constructor.
26
+ # Build a grammar with one empty rule as start/start rule.
27
+ def initialize()
28
+ @start = Production.new
29
+ @productions = [ start ]
30
+ @trace = false
31
+ end
32
+
33
+ public
34
+
35
+ # Emit a text representation of the grammar.
36
+ # Each production rule is emitted per line.
37
+ # @return [String]
38
+ def to_string()
39
+ rule_text = productions.map(&:to_string).join("\n")
40
+ return rule_text
41
+ end
42
+
43
+
44
+ # Add a given production to the grammar.
45
+ # @param aProduction [Production]
46
+ def add_production(aProduction)
47
+ # TODO: remove output
48
+ puts "Adding #{aProduction.object_id}" if trace
49
+ puts aProduction.to_string if trace
50
+ productions << aProduction
51
+ end
52
+
53
+
54
+ # Remove a production with given index from the grammar
55
+ # @param anIndex [Fixnum]
56
+ # @return [Production] the production removed from the grammar.
57
+ def remove_production(anIndex)
58
+ puts "Before production removal #{productions[anIndex].object_id}" if trace
59
+ puts to_string if trace
60
+ prod = productions.delete_at(anIndex)
61
+ # TODO: remove output
62
+ puts('Removed: ' + prod.to_string) if trace
63
+ prod.clear_rhs
64
+
65
+ return prod
66
+ end
67
+
68
+
69
+ # Add the given token to the grammar.
70
+ # Append the token to the rhs of the start/start rule.
71
+ # @param aToken [Object] input token to add
72
+ def add_token(aToken)
73
+ append_symbol_to(start, aToken)
74
+ end
75
+
76
+ # Part of the 'visitee' role in the Visitor design pattern.
77
+ # A visitee is expected to accept the visit from a visitor object
78
+ # @param aVisitor [GrammarVisitor] the visitor object
79
+ def accept(aVisitor)
80
+ aVisitor.start_visit_grammar(self)
81
+
82
+ # Let's proceed with the visit of productions
83
+ productions.each { |prod| prod.accept(aVisitor) }
84
+
85
+ aVisitor.end_visit_grammar(self)
86
+ end
87
+
88
+ # Factory method. Returns a visitor for this grammar.
89
+ # @return [GrammarVisitor]
90
+ def visitor()
91
+ return GrammarVisitor.new(self)
92
+ end
93
+
94
+ protected
95
+
96
+ # Append a given symbol to the rhs of passed production.
97
+ # @param aProduction [Production]
98
+ # @param aSymbol [Object]
99
+ def append_symbol_to(aProduction, aSymbol)
100
+ aProduction.append_symbol(aSymbol)
101
+ end
102
+ end # class
103
+
104
+ end # module
105
+
106
+ # End of file
@@ -1,39 +1,39 @@
1
- module Sequitur
2
-
3
- # Namespace dedicated to grammar formatters.
4
- module Formatter
5
-
6
- # Superclass for grammar formatters.
7
- class BaseFormatter
8
- # The IO output stream in which the formatter's result will be sent.
9
- attr(:output)
10
-
11
- # Constructor.
12
- # @param anIO [IO] an output IO where the formatter's result will
13
- # be placed.
14
- def initialize(anIO)
15
- @output = anIO
16
- end
17
-
18
- public
19
-
20
- # Given a grammar or a grammar visitor, perform the visit
21
- # and render the visit events in the output stream.
22
- # @param aGrmOrVisitor [DynamicGrammar or GrammarVisitor]
23
- def render(aGrmOrVisitor)
24
- if aGrmOrVisitor.kind_of?(GrammarVisitor)
25
- a_visitor = aGrmOrVisitor
26
- else
27
- a_visitor = aGrmOrVisitor.visitor
28
- end
29
-
30
- a_visitor.subscribe(self)
31
- a_visitor.start
32
- a_visitor.unsubscribe(self)
33
- end
34
-
35
- end # class
36
- end # module
37
- end # module
38
-
39
- # End of file
1
+ module Sequitur
2
+
3
+ # Namespace dedicated to grammar formatters.
4
+ module Formatter
5
+
6
+ # Superclass for grammar formatters.
7
+ class BaseFormatter
8
+ # The IO output stream in which the formatter's result will be sent.
9
+ attr(:output)
10
+
11
+ # Constructor.
12
+ # @param anIO [IO] an output IO where the formatter's result will
13
+ # be placed.
14
+ def initialize(anIO)
15
+ @output = anIO
16
+ end
17
+
18
+ public
19
+
20
+ # Given a grammar or a grammar visitor, perform the visit
21
+ # and render the visit events in the output stream.
22
+ # @param aGrmOrVisitor [DynamicGrammar or GrammarVisitor]
23
+ def render(aGrmOrVisitor)
24
+ if aGrmOrVisitor.kind_of?(GrammarVisitor)
25
+ a_visitor = aGrmOrVisitor
26
+ else
27
+ a_visitor = aGrmOrVisitor.visitor
28
+ end
29
+
30
+ a_visitor.subscribe(self)
31
+ a_visitor.start
32
+ a_visitor.unsubscribe(self)
33
+ end
34
+
35
+ end # class
36
+ end # module
37
+ end # module
38
+
39
+ # End of file
@@ -1,95 +1,95 @@
1
- require_relative 'base_formatter'
2
-
3
- module Sequitur
4
- module Formatter
5
-
6
- # A formatter class that can render a dynamic grammar in plain text.
7
- # @example
8
- # some_grammar = ... # Points to a DynamicGrammar-like object
9
- # # Output the result to the standard console output
10
- # formatter = Sequitur::Formatter::BaseText.new(STDOUT)
11
- # # Render the grammar (through a visitor)
12
- # formatter.run(some_grammar.visitor)
13
- class BaseText < BaseFormatter
14
-
15
- # Constructor.
16
- # @param anIO [IO] The output stream to which the rendered grammar
17
- # is written.
18
- def initialize(anIO)
19
- super(anIO)
20
- @prod_lookup = {}
21
- end
22
-
23
- public
24
-
25
- # Method called by a GrammarVisitor to which the formatter subscribed.
26
- # Notification of a visit event: the visitor is about to visit a grammar
27
- # @param aGrammar [DynamicGrammar-like object]
28
- def before_grammar(aGrammar)
29
- aGrammar.productions.each_with_index do |a_prod, index|
30
- prod_lookup[a_prod] = index
31
- end
32
- end
33
-
34
- # Method called by a GrammarVisitor to which the formatter subscribed.
35
- # Notification of a visit event: the visitor is about to visit
36
- # a production
37
- # @param aProduction [aProduction]
38
- def before_production(aProduction)
39
- p_name = prod_name(aProduction)
40
- output.print p_name
41
- end
42
-
43
- # Method called by a GrammarVisitor to which the formatter subscribed.
44
- # Notification of a visit event: the visitor is about to visit
45
- # the rhs of a production
46
- # @param _ [Array]
47
- def before_rhs(_)
48
- output.print ' :'
49
- end
50
-
51
- # Method called by a GrammarVisitor to which the formatter subscribed.
52
- # Notification of a visit event: the visitor is about to visit
53
- # a terminal symbol from the rhs of a production
54
- # @param aSymbol [Object]
55
- def before_terminal(aSymbol)
56
- output.print " #{aSymbol}"
57
- end
58
-
59
- # Method called by a GrammarVisitor to which the formatter subscribed.
60
- # Notification of a visit event: the visitor is about to visit
61
- # a non-terminal (= an allusion to a production) in the rhs of a
62
- # production
63
- # @param aProduction [Production] a production occurring in the rhs
64
- def before_non_terminal(aProduction)
65
- p_name = prod_name(aProduction)
66
- output.print " #{p_name}"
67
- end
68
-
69
- # Method called by a GrammarVisitor to which the formatter subscribed.
70
- # Notification of a visit event: the visitor complete the visit
71
- # of a production
72
- def after_production(_)
73
- output.print ".\n"
74
- end
75
-
76
- private
77
-
78
- # Read accessor of the production lookup
79
- def prod_lookup()
80
- return @prod_lookup
81
- end
82
-
83
- # Generate a name of a given production.
84
- # @param aProduction [Production]
85
- def prod_name(aProduction)
86
- prod_index = prod_lookup[aProduction]
87
- name = (prod_index == 0) ? 'start' : "P#{prod_index}"
88
- return name
89
- end
90
-
91
- end # class
92
- end # module
93
- end # module
94
-
95
- # End of file
1
+ require_relative 'base_formatter'
2
+
3
+ module Sequitur
4
+ module Formatter
5
+
6
+ # A formatter class that can render a dynamic grammar in plain text.
7
+ # @example
8
+ # some_grammar = ... # Points to a DynamicGrammar-like object
9
+ # # Output the result to the standard console output
10
+ # formatter = Sequitur::Formatter::BaseText.new(STDOUT)
11
+ # # Render the grammar (through a visitor)
12
+ # formatter.run(some_grammar.visitor)
13
+ class BaseText < BaseFormatter
14
+
15
+ # Constructor.
16
+ # @param anIO [IO] The output stream to which the rendered grammar
17
+ # is written.
18
+ def initialize(anIO)
19
+ super(anIO)
20
+ @prod_lookup = {}
21
+ end
22
+
23
+ public
24
+
25
+ # Method called by a GrammarVisitor to which the formatter subscribed.
26
+ # Notification of a visit event: the visitor is about to visit a grammar
27
+ # @param aGrammar [DynamicGrammar-like object]
28
+ def before_grammar(aGrammar)
29
+ aGrammar.productions.each_with_index do |a_prod, index|
30
+ prod_lookup[a_prod] = index
31
+ end
32
+ end
33
+
34
+ # Method called by a GrammarVisitor to which the formatter subscribed.
35
+ # Notification of a visit event: the visitor is about to visit
36
+ # a production
37
+ # @param aProduction [aProduction]
38
+ def before_production(aProduction)
39
+ p_name = prod_name(aProduction)
40
+ output.print p_name
41
+ end
42
+
43
+ # Method called by a GrammarVisitor to which the formatter subscribed.
44
+ # Notification of a visit event: the visitor is about to visit
45
+ # the rhs of a production
46
+ # @param _ [Array]
47
+ def before_rhs(_)
48
+ output.print ' :'
49
+ end
50
+
51
+ # Method called by a GrammarVisitor to which the formatter subscribed.
52
+ # Notification of a visit event: the visitor is about to visit
53
+ # a terminal symbol from the rhs of a production
54
+ # @param aSymbol [Object]
55
+ def before_terminal(aSymbol)
56
+ output.print " #{aSymbol}"
57
+ end
58
+
59
+ # Method called by a GrammarVisitor to which the formatter subscribed.
60
+ # Notification of a visit event: the visitor is about to visit
61
+ # a non-terminal (= an allusion to a production) in the rhs of a
62
+ # production
63
+ # @param aProduction [Production] a production occurring in the rhs
64
+ def before_non_terminal(aProduction)
65
+ p_name = prod_name(aProduction)
66
+ output.print " #{p_name}"
67
+ end
68
+
69
+ # Method called by a GrammarVisitor to which the formatter subscribed.
70
+ # Notification of a visit event: the visitor complete the visit
71
+ # of a production
72
+ def after_production(_)
73
+ output.print ".\n"
74
+ end
75
+
76
+ private
77
+
78
+ # Read accessor of the production lookup
79
+ def prod_lookup()
80
+ return @prod_lookup
81
+ end
82
+
83
+ # Generate a name of a given production.
84
+ # @param aProduction [Production]
85
+ def prod_name(aProduction)
86
+ prod_index = prod_lookup[aProduction]
87
+ name = (prod_index == 0) ? 'start' : "P#{prod_index}"
88
+ return name
89
+ end
90
+
91
+ end # class
92
+ end # module
93
+ end # module
94
+
95
+ # End of file