rley 0.7.03 → 0.7.08
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 +362 -62
- data/.travis.yml +6 -7
- data/CHANGELOG.md +20 -1
- data/LICENSE.txt +1 -1
- data/README.md +6 -7
- data/Rakefile +2 -0
- data/appveyor.yml +2 -4
- data/examples/NLP/benchmark_pico_en.rb +2 -0
- data/examples/NLP/engtagger.rb +193 -188
- data/examples/NLP/nano_eng/nano_en_demo.rb +2 -0
- data/examples/NLP/nano_eng/nano_grammar.rb +7 -5
- data/examples/NLP/pico_en_demo.rb +2 -0
- data/examples/data_formats/JSON/cli_options.rb +3 -1
- data/examples/data_formats/JSON/json_ast_builder.rb +14 -9
- data/examples/data_formats/JSON/json_ast_nodes.rb +14 -21
- data/examples/data_formats/JSON/json_demo.rb +2 -0
- data/examples/data_formats/JSON/json_grammar.rb +4 -2
- data/examples/data_formats/JSON/json_lexer.rb +10 -8
- data/examples/data_formats/JSON/json_minifier.rb +3 -1
- data/examples/general/calc_iter1/calc_ast_builder.rb +15 -10
- data/examples/general/calc_iter1/calc_ast_nodes.rb +25 -37
- data/examples/general/calc_iter1/calc_demo.rb +2 -0
- data/examples/general/calc_iter1/calc_grammar.rb +4 -2
- data/examples/general/calc_iter1/calc_lexer.rb +8 -4
- data/examples/general/calc_iter1/spec/calculator_spec.rb +7 -5
- data/examples/general/calc_iter2/calc_ast_builder.rb +7 -3
- data/examples/general/calc_iter2/calc_ast_nodes.rb +29 -43
- data/examples/general/calc_iter2/calc_demo.rb +2 -0
- data/examples/general/calc_iter2/calc_grammar.rb +5 -3
- data/examples/general/calc_iter2/calc_lexer.rb +13 -10
- data/examples/general/calc_iter2/spec/calculator_spec.rb +28 -26
- data/examples/general/left.rb +4 -2
- data/examples/general/right.rb +4 -2
- data/lib/rley.rb +2 -0
- data/lib/rley/base/base_parser.rb +2 -0
- data/lib/rley/base/dotted_item.rb +38 -41
- data/lib/rley/base/grm_items_builder.rb +2 -0
- data/lib/rley/constants.rb +5 -3
- data/lib/rley/engine.rb +22 -24
- data/lib/rley/formatter/asciitree.rb +6 -4
- data/lib/rley/formatter/base_formatter.rb +2 -0
- data/lib/rley/formatter/bracket_notation.rb +3 -8
- data/lib/rley/formatter/debug.rb +8 -6
- data/lib/rley/formatter/json.rb +4 -2
- data/lib/rley/gfg/call_edge.rb +3 -1
- data/lib/rley/gfg/edge.rb +7 -5
- data/lib/rley/gfg/end_vertex.rb +4 -6
- data/lib/rley/gfg/epsilon_edge.rb +3 -5
- data/lib/rley/gfg/grm_flow_graph.rb +31 -25
- data/lib/rley/gfg/item_vertex.rb +12 -22
- data/lib/rley/gfg/non_terminal_vertex.rb +6 -4
- data/lib/rley/gfg/return_edge.rb +2 -0
- data/lib/rley/gfg/scan_edge.rb +3 -1
- data/lib/rley/gfg/shortcut_edge.rb +4 -2
- data/lib/rley/gfg/start_vertex.rb +6 -8
- data/lib/rley/gfg/vertex.rb +47 -41
- data/lib/rley/lexical/token.rb +3 -1
- data/lib/rley/lexical/token_range.rb +8 -6
- data/lib/rley/parse_forest_visitor.rb +7 -5
- data/lib/rley/parse_rep/ast_base_builder.rb +11 -11
- data/lib/rley/parse_rep/cst_builder.rb +7 -4
- data/lib/rley/parse_rep/parse_forest_builder.rb +36 -25
- data/lib/rley/parse_rep/parse_forest_factory.rb +5 -3
- data/lib/rley/parse_rep/parse_rep_creator.rb +18 -13
- data/lib/rley/parse_rep/parse_tree_builder.rb +15 -15
- data/lib/rley/parse_rep/parse_tree_factory.rb +27 -25
- data/lib/rley/parse_tree_visitor.rb +3 -1
- data/lib/rley/parser/error_reason.rb +9 -8
- data/lib/rley/parser/gfg_chart.rb +54 -22
- data/lib/rley/parser/gfg_earley_parser.rb +3 -1
- data/lib/rley/parser/gfg_parsing.rb +51 -31
- data/lib/rley/parser/parse_entry.rb +29 -33
- data/lib/rley/parser/parse_entry_set.rb +32 -27
- data/lib/rley/parser/parse_entry_tracker.rb +6 -4
- data/lib/rley/parser/parse_state.rb +18 -21
- data/lib/rley/parser/parse_state_tracker.rb +6 -4
- data/lib/rley/parser/parse_tracer.rb +15 -13
- data/lib/rley/parser/parse_walker_factory.rb +28 -29
- data/lib/rley/parser/state_set.rb +11 -10
- data/lib/rley/ptree/non_terminal_node.rb +10 -6
- data/lib/rley/ptree/parse_tree.rb +6 -4
- data/lib/rley/ptree/parse_tree_node.rb +7 -5
- data/lib/rley/ptree/terminal_node.rb +9 -7
- data/lib/rley/rley_error.rb +12 -10
- data/lib/rley/sppf/alternative_node.rb +8 -6
- data/lib/rley/sppf/composite_node.rb +9 -7
- data/lib/rley/sppf/epsilon_node.rb +5 -3
- data/lib/rley/sppf/leaf_node.rb +5 -3
- data/lib/rley/sppf/non_terminal_node.rb +2 -0
- data/lib/rley/sppf/parse_forest.rb +19 -17
- data/lib/rley/sppf/sppf_node.rb +9 -8
- data/lib/rley/sppf/token_node.rb +5 -3
- data/lib/rley/syntax/grammar.rb +7 -5
- data/lib/rley/syntax/grammar_builder.rb +11 -9
- data/lib/rley/syntax/grm_symbol.rb +8 -6
- data/lib/rley/syntax/literal.rb +2 -0
- data/lib/rley/syntax/non_terminal.rb +11 -15
- data/lib/rley/syntax/production.rb +13 -11
- data/lib/rley/syntax/symbol_seq.rb +10 -10
- data/lib/rley/syntax/terminal.rb +6 -5
- data/lib/rley/syntax/verbatim_symbol.rb +5 -3
- data/lib/support/base_tokenizer.rb +23 -20
- data/spec/rley/base/dotted_item_spec.rb +4 -2
- data/spec/rley/base/grm_items_builder_spec.rb +2 -0
- data/spec/rley/engine_spec.rb +47 -9
- data/spec/rley/formatter/asciitree_spec.rb +11 -9
- data/spec/rley/formatter/bracket_notation_spec.rb +16 -14
- data/spec/rley/formatter/debug_spec.rb +4 -2
- data/spec/rley/formatter/json_spec.rb +5 -3
- data/spec/rley/gfg/call_edge_spec.rb +2 -0
- data/spec/rley/gfg/edge_spec.rb +2 -0
- data/spec/rley/gfg/end_vertex_spec.rb +7 -5
- data/spec/rley/gfg/epsilon_edge_spec.rb +2 -0
- data/spec/rley/gfg/grm_flow_graph_spec.rb +2 -0
- data/spec/rley/gfg/item_vertex_spec.rb +12 -10
- data/spec/rley/gfg/non_terminal_vertex_spec.rb +5 -3
- data/spec/rley/gfg/return_edge_spec.rb +2 -0
- data/spec/rley/gfg/scan_edge_spec.rb +2 -0
- data/spec/rley/gfg/shortcut_edge_spec.rb +3 -1
- data/spec/rley/gfg/start_vertex_spec.rb +7 -5
- data/spec/rley/gfg/vertex_spec.rb +5 -3
- data/spec/rley/lexical/token_range_spec.rb +18 -16
- data/spec/rley/lexical/token_spec.rb +4 -2
- data/spec/rley/parse_forest_visitor_spec.rb +167 -163
- data/spec/rley/parse_rep/ambiguous_parse_spec.rb +46 -44
- data/spec/rley/parse_rep/ast_builder_spec.rb +8 -6
- data/spec/rley/parse_rep/cst_builder_spec.rb +7 -5
- data/spec/rley/parse_rep/groucho_spec.rb +25 -25
- data/spec/rley/parse_rep/parse_forest_builder_spec.rb +28 -26
- data/spec/rley/parse_rep/parse_forest_factory_spec.rb +8 -6
- data/spec/rley/parse_rep/parse_tree_factory_spec.rb +4 -2
- data/spec/rley/parse_tree_visitor_spec.rb +12 -8
- data/spec/rley/parser/error_reason_spec.rb +8 -6
- data/spec/rley/parser/gfg_chart_spec.rb +17 -4
- data/spec/rley/parser/gfg_earley_parser_spec.rb +16 -11
- data/spec/rley/parser/gfg_parsing_spec.rb +41 -252
- data/spec/rley/parser/parse_entry_set_spec.rb +2 -0
- data/spec/rley/parser/parse_entry_spec.rb +21 -19
- data/spec/rley/parser/parse_state_spec.rb +7 -5
- data/spec/rley/parser/parse_tracer_spec.rb +16 -14
- data/spec/rley/parser/parse_walker_factory_spec.rb +10 -8
- data/spec/rley/parser/state_set_spec.rb +24 -22
- data/spec/rley/ptree/non_terminal_node_spec.rb +7 -3
- data/spec/rley/ptree/parse_tree_node_spec.rb +6 -4
- data/spec/rley/ptree/parse_tree_spec.rb +2 -0
- data/spec/rley/ptree/terminal_node_spec.rb +8 -6
- data/spec/rley/sppf/alternative_node_spec.rb +8 -6
- data/spec/rley/sppf/non_terminal_node_spec.rb +5 -3
- data/spec/rley/sppf/token_node_spec.rb +6 -4
- data/spec/rley/support/ambiguous_grammar_helper.rb +5 -4
- data/spec/rley/support/expectation_helper.rb +2 -0
- data/spec/rley/support/grammar_abc_helper.rb +4 -4
- data/spec/rley/support/grammar_ambig01_helper.rb +6 -5
- data/spec/rley/support/grammar_arr_int_helper.rb +6 -5
- data/spec/rley/support/grammar_b_expr_helper.rb +6 -5
- data/spec/rley/support/grammar_helper.rb +2 -0
- data/spec/rley/support/grammar_l0_helper.rb +15 -16
- data/spec/rley/support/grammar_pb_helper.rb +8 -5
- data/spec/rley/support/grammar_sppf_helper.rb +3 -1
- data/spec/rley/syntax/grammar_builder_spec.rb +7 -5
- data/spec/rley/syntax/grammar_spec.rb +8 -6
- data/spec/rley/syntax/grm_symbol_spec.rb +3 -1
- data/spec/rley/syntax/literal_spec.rb +2 -0
- data/spec/rley/syntax/non_terminal_spec.rb +10 -8
- data/spec/rley/syntax/production_spec.rb +15 -13
- data/spec/rley/syntax/symbol_seq_spec.rb +4 -2
- data/spec/rley/syntax/terminal_spec.rb +7 -5
- data/spec/rley/syntax/verbatim_symbol_spec.rb +3 -1
- data/spec/spec_helper.rb +2 -12
- data/spec/support/base_tokenizer_spec.rb +9 -2
- metadata +21 -63
- data/.simplecov +0 -7
- data/Gemfile +0 -8
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'parse_tree_node' # Load superclass
|
2
4
|
|
3
5
|
module Rley # This module is used as a namespace
|
@@ -16,20 +18,22 @@ module Rley # This module is used as a namespace
|
|
16
18
|
def add_subnode(aSubnode)
|
17
19
|
subnodes.unshift(aSubnode)
|
18
20
|
end
|
19
|
-
|
21
|
+
|
20
22
|
# Emit a (formatted) string representation of the node.
|
21
23
|
# Mainly used for diagnosis/debugging purposes.
|
24
|
+
# rubocop: disable Style/StringConcatenation
|
22
25
|
def to_string(indentation)
|
23
26
|
connector = '+- '
|
24
27
|
selfie = super(indentation)
|
25
28
|
prefix = "\n" + (' ' * connector.size * indentation) + connector
|
26
|
-
subnodes_repr = subnodes.reduce('') do |sub_result, subnode|
|
27
|
-
sub_result << prefix + subnode.to_string(indentation + 1)
|
29
|
+
subnodes_repr = subnodes.reduce(+'') do |sub_result, subnode|
|
30
|
+
sub_result << prefix + subnode.to_string(indentation + 1)
|
28
31
|
end
|
29
|
-
|
30
|
-
|
32
|
+
|
33
|
+
selfie + subnodes_repr
|
31
34
|
end
|
32
|
-
|
35
|
+
# rubocop: enable Style/StringConcatenation
|
36
|
+
|
33
37
|
# Part of the 'visitee' role in Visitor design pattern.
|
34
38
|
# @param aVisitor[ParseTreeVisitor] the visitor
|
35
39
|
def accept(aVisitor)
|
@@ -1,15 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'terminal_node'
|
2
4
|
require_relative 'non_terminal_node'
|
3
5
|
|
4
6
|
module Rley # This module is used as a namespace
|
5
7
|
module PTree # This module is used as a namespace
|
6
8
|
# A parse tree (a.k.a. concrete syntax tree) is a tree-based representation
|
7
|
-
# for the parse that corresponds to the input text. In a parse tree,
|
9
|
+
# for the parse that corresponds to the input text. In a parse tree,
|
8
10
|
# a node corresponds to a grammar symbol used during the parsing:
|
9
11
|
# - a leaf node maps to a terminal symbol occurring in
|
10
12
|
# the input, and
|
11
13
|
# - a intermediate node maps to a non-terminal node reduced
|
12
|
-
# during the parse.
|
14
|
+
# during the parse.
|
13
15
|
# The root node corresponds to the main/start symbol of the grammar.
|
14
16
|
class ParseTree
|
15
17
|
# @return [ParseTreeNode] The root node of the tree.
|
@@ -19,7 +21,7 @@ module Rley # This module is used as a namespace
|
|
19
21
|
def initialize(theRootNode)
|
20
22
|
@root = theRootNode
|
21
23
|
end
|
22
|
-
|
24
|
+
|
23
25
|
# Notification from the builder telling that the parse tree construction
|
24
26
|
# is over. This method can be overriden.
|
25
27
|
def done!
|
@@ -33,7 +35,7 @@ module Rley # This module is used as a namespace
|
|
33
35
|
aVisitor.start_visit_ptree(self)
|
34
36
|
|
35
37
|
# Let's proceed with the visit of nodes
|
36
|
-
root
|
38
|
+
root&.accept(aVisitor)
|
37
39
|
|
38
40
|
aVisitor.end_visit_ptree(self)
|
39
41
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative '../lexical/token_range'
|
2
4
|
|
3
5
|
module Rley # This module is used as a namespace
|
@@ -13,9 +15,9 @@ module Rley # This module is used as a namespace
|
|
13
15
|
@symbol = aSymbol
|
14
16
|
@range = Lexical::TokenRange.new(aRange)
|
15
17
|
end
|
16
|
-
|
18
|
+
|
17
19
|
# Notify the builder that the construction is over
|
18
|
-
def done!
|
20
|
+
def done!
|
19
21
|
# Do nothing
|
20
22
|
end
|
21
23
|
|
@@ -27,13 +29,13 @@ module Rley # This module is used as a namespace
|
|
27
29
|
# Emit a (formatted) string representation of the node.
|
28
30
|
# Mainly used for diagnosis/debugging purposes.
|
29
31
|
def to_string(indentation)
|
30
|
-
|
32
|
+
"#{symbol.name}#{range.to_string(indentation)}"
|
31
33
|
end
|
32
34
|
|
33
35
|
# Emit a short string representation of the node.
|
34
36
|
# Mainly used for diagnosis/debugging purposes.
|
35
|
-
def to_s
|
36
|
-
|
37
|
+
def to_s
|
38
|
+
"#{symbol.name}#{range.to_string(0)}"
|
37
39
|
end
|
38
40
|
end # class
|
39
41
|
end # module
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'parse_tree_node' # Load superclass
|
2
4
|
|
3
5
|
module Rley # This module is used as a namespace
|
@@ -7,10 +9,10 @@ module Rley # This module is used as a namespace
|
|
7
9
|
attr_reader(:token)
|
8
10
|
|
9
11
|
# @param aToken [Lexical::Token] Input Token object
|
10
|
-
# @param aPos [Integer] position of the token in the input stream.
|
12
|
+
# @param aPos [Integer] position of the token in the input stream.
|
11
13
|
def initialize(aToken, aPos)
|
12
|
-
# (major, minor) =
|
13
|
-
|
14
|
+
# (major, minor) =
|
15
|
+
|
14
16
|
# Use '1.class' trick to support both Integer and Fixnum classes
|
15
17
|
range = aPos.kind_of?(1.class) ? { low: aPos, high: aPos + 1 } : aPos
|
16
18
|
super(aToken.terminal, range)
|
@@ -22,18 +24,18 @@ module Rley # This module is used as a namespace
|
|
22
24
|
def to_string(indentation)
|
23
25
|
return super + ": '#{token.lexeme}'"
|
24
26
|
end
|
25
|
-
|
27
|
+
|
26
28
|
# Emit a short string representation of the node.
|
27
29
|
# Mainly used for diagnosis/debugging purposes.
|
28
|
-
def to_s
|
30
|
+
def to_s
|
29
31
|
return super + ": '#{token.lexeme}'"
|
30
|
-
end
|
32
|
+
end
|
31
33
|
|
32
34
|
# Part of the 'visitee' role in Visitor design pattern.
|
33
35
|
# @param aVisitor[ParseTreeVisitor] the visitor
|
34
36
|
def accept(aVisitor)
|
35
37
|
aVisitor.visit_terminal(self)
|
36
|
-
end
|
38
|
+
end
|
37
39
|
end # class
|
38
40
|
end # module
|
39
41
|
end # module
|
data/lib/rley/rley_error.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# File: rley_error.rb
|
4
|
+
|
5
|
+
module Rley # Module used as a namespace
|
6
|
+
# @abstract
|
7
|
+
# Base class for any exception explicitly raised by Rley code.
|
8
|
+
class RleyError < StandardError
|
9
|
+
end # class
|
10
|
+
end # module
|
11
|
+
|
12
|
+
# End of file
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'composite_node'
|
2
4
|
|
3
5
|
module Rley # This module is used as a namespace
|
@@ -11,10 +13,10 @@ module Rley # This module is used as a namespace
|
|
11
13
|
# @return [Syntax::NonTerminal] Link to lhs symbol
|
12
14
|
attr_reader(:symbol)
|
13
15
|
|
14
|
-
# @param aVertex [GFG::ItemVertex]
|
15
|
-
# A GFG vertex that corresponds to a dotted item
|
16
|
+
# @param aVertex [GFG::ItemVertex]
|
17
|
+
# A GFG vertex that corresponds to a dotted item
|
16
18
|
# with the dot at the end) for the alternative under consideration.
|
17
|
-
# @param aRange [Lexical::TokenRange]
|
19
|
+
# @param aRange [Lexical::TokenRange]
|
18
20
|
# A range of token indices corresponding to this node.
|
19
21
|
def initialize(aVertex, aRange)
|
20
22
|
super(aRange)
|
@@ -26,14 +28,14 @@ module Rley # This module is used as a namespace
|
|
26
28
|
# Mainly used for diagnosis/debugging purposes.
|
27
29
|
# @return [String]
|
28
30
|
def to_string(indentation)
|
29
|
-
|
31
|
+
"Alt(#{label})#{range.to_string(indentation)}"
|
30
32
|
end
|
31
|
-
|
33
|
+
|
32
34
|
# Part of the 'visitee' role in Visitor design pattern.
|
33
35
|
# @param aVisitor[ParseTreeVisitor] the visitor
|
34
36
|
def accept(aVisitor)
|
35
37
|
aVisitor.visit_alternative(self)
|
36
|
-
end
|
38
|
+
end
|
37
39
|
end # class
|
38
40
|
end # module
|
39
41
|
end # module
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'sppf_node'
|
2
4
|
|
3
5
|
module Rley # This module is used as a namespace
|
@@ -7,11 +9,11 @@ module Rley # This module is used as a namespace
|
|
7
9
|
class CompositeNode < SPPFNode
|
8
10
|
# @return [Array<SPFFNode>] Sub-nodes (children).
|
9
11
|
attr_reader(:subnodes)
|
10
|
-
|
11
|
-
alias children subnodes
|
12
|
+
|
13
|
+
alias children subnodes
|
12
14
|
|
13
15
|
# Constructor
|
14
|
-
# @param aRange [Lexical::TokenRange]
|
16
|
+
# @param aRange [Lexical::TokenRange]
|
15
17
|
def initialize(aRange)
|
16
18
|
super(aRange)
|
17
19
|
@subnodes = []
|
@@ -22,14 +24,14 @@ module Rley # This module is used as a namespace
|
|
22
24
|
def add_subnode(aSubnode)
|
23
25
|
subnodes.unshift(aSubnode)
|
24
26
|
end
|
25
|
-
|
27
|
+
|
26
28
|
# @return [String] a text representation of the node.
|
27
|
-
def inspect
|
29
|
+
def inspect
|
28
30
|
key
|
29
|
-
end
|
31
|
+
end
|
30
32
|
|
31
33
|
# @return [String]
|
32
|
-
def key
|
34
|
+
def key
|
33
35
|
@key ||= to_string(0)
|
34
36
|
end
|
35
37
|
end # class
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'leaf_node'
|
2
4
|
|
3
5
|
module Rley # This module is used as a namespace
|
@@ -15,14 +17,14 @@ module Rley # This module is used as a namespace
|
|
15
17
|
# Mainly used for diagnosis/debugging purposes.
|
16
18
|
# @return [String]
|
17
19
|
def to_string(indentation)
|
18
|
-
|
20
|
+
"_#{range.to_string(indentation)}"
|
19
21
|
end
|
20
|
-
|
22
|
+
|
21
23
|
# Part of the 'visitee' role in Visitor design pattern.
|
22
24
|
# @param aVisitor[ParseTreeVisitor] the visitor
|
23
25
|
def accept(aVisitor)
|
24
26
|
aVisitor.visit_epsilon(self)
|
25
|
-
end
|
27
|
+
end
|
26
28
|
end # class
|
27
29
|
end # module
|
28
30
|
end # module
|
data/lib/rley/sppf/leaf_node.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'sppf_node'
|
2
4
|
|
3
5
|
module Rley # This module is used as a namespace
|
@@ -6,14 +8,14 @@ module Rley # This module is used as a namespace
|
|
6
8
|
# child node.
|
7
9
|
class LeafNode < SPPFNode
|
8
10
|
# @return [String] a text representation of the node.
|
9
|
-
def inspect
|
11
|
+
def inspect
|
10
12
|
key
|
11
13
|
end
|
12
14
|
|
13
15
|
# @return [String]
|
14
|
-
def key
|
16
|
+
def key
|
15
17
|
@key ||= to_string(0)
|
16
|
-
end
|
18
|
+
end
|
17
19
|
end # class
|
18
20
|
end # module
|
19
21
|
end # module
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'token_node'
|
2
4
|
require_relative 'non_terminal_node'
|
3
5
|
require_relative 'alternative_node'
|
@@ -5,19 +7,19 @@ require_relative 'alternative_node'
|
|
5
7
|
module Rley # This module is used as a namespace
|
6
8
|
module SPPF # This module is used as a namespace
|
7
9
|
# In an ambiguous grammar there are valid inputs that can result in multiple
|
8
|
-
# parse trees. A set of parse trees is commonly referred to as a parse
|
9
|
-
# forest. More specifically a parse forest is a graph data
|
10
|
+
# parse trees. A set of parse trees is commonly referred to as a parse
|
11
|
+
# forest. More specifically a parse forest is a graph data
|
10
12
|
# structure designed to represent a set of equally syntactically correct
|
11
13
|
# parse trees. Parse forests generated by Rley are so-called Shared Packed
|
12
|
-
# Parse Forests (SPPF). SPPFs allow very compact representation of parse
|
14
|
+
# Parse Forests (SPPF). SPPFs allow very compact representation of parse
|
13
15
|
# trees by sharing common sub-tree amongst the parse trees.
|
14
16
|
class ParseForest
|
15
17
|
# The root node of the forest
|
16
18
|
attr_reader(:root)
|
17
|
-
|
19
|
+
|
18
20
|
# A Hash with pairs of the kind node key => node
|
19
21
|
attr_reader(:key2node)
|
20
|
-
|
22
|
+
|
21
23
|
# A setter that tells that the parse is ambiguous.
|
22
24
|
attr_writer(:is_ambiguous)
|
23
25
|
|
@@ -28,34 +30,34 @@ module Rley # This module is used as a namespace
|
|
28
30
|
@key2node = {}
|
29
31
|
@is_ambiguous = false
|
30
32
|
end
|
31
|
-
|
33
|
+
|
32
34
|
# Notification that the SPPF construction is over
|
33
35
|
def done!
|
34
36
|
# Do nothing
|
35
37
|
end
|
36
|
-
|
38
|
+
|
37
39
|
# Returns true if the given node is present in the forest.
|
38
40
|
def include?(aNode)
|
39
|
-
|
41
|
+
key2node.include?(aNode)
|
40
42
|
end
|
41
|
-
|
43
|
+
|
42
44
|
# Returns true if the parse encountered a structural ambiguity
|
43
45
|
# (i.e. more than one parse tree for the given input)
|
44
|
-
def ambiguous?
|
45
|
-
|
46
|
+
def ambiguous?
|
47
|
+
@is_ambiguous
|
46
48
|
end
|
47
|
-
|
48
|
-
# Create an Enumerator that helps to iterate over the possible
|
49
|
-
# parse trees. That enumerator will generate a parse tree when
|
49
|
+
|
50
|
+
# Create an Enumerator that helps to iterate over the possible
|
51
|
+
# parse trees. That enumerator will generate a parse tree when
|
50
52
|
# called with `next` method.
|
51
53
|
# @return [Enumerator]
|
52
|
-
def to_ptree_enum
|
54
|
+
def to_ptree_enum
|
53
55
|
# How to implement?
|
54
56
|
# One visits the forest => beware of dependency
|
55
57
|
# At each visited item create a corresponding tree node.
|
56
58
|
# At end of visit & stack not empty
|
57
59
|
# Re-generate another ptree
|
58
|
-
end
|
60
|
+
end
|
59
61
|
|
60
62
|
# Part of the 'visitee' role in the Visitor design pattern.
|
61
63
|
# A visitee is expected to accept the visit from a visitor object
|
@@ -64,7 +66,7 @@ module Rley # This module is used as a namespace
|
|
64
66
|
aVisitor.start_visit_pforest(self)
|
65
67
|
|
66
68
|
# Let's proceed with the visit of nodes
|
67
|
-
root
|
69
|
+
root&.accept(aVisitor)
|
68
70
|
|
69
71
|
aVisitor.end_visit_pforest(self)
|
70
72
|
end
|
data/lib/rley/sppf/sppf_node.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative '../lexical/token_range'
|
2
4
|
|
3
5
|
module Rley # This module is used as a namespace
|
@@ -5,23 +7,22 @@ module Rley # This module is used as a namespace
|
|
5
7
|
# Abstract class. The generalization for all kinds of nodes
|
6
8
|
# occurring in a shared packed parse forest (SPPF).
|
7
9
|
class SPPFNode
|
8
|
-
|
9
|
-
# @return [Lexical::TokenRange]
|
10
|
+
# @return [Lexical::TokenRange]
|
10
11
|
# A range of token indices corresponding to this node.
|
11
12
|
attr_reader(:range)
|
12
|
-
|
13
|
+
|
13
14
|
# Constructor
|
14
15
|
# @param aRange [Lexical::TokenRange]
|
15
16
|
def initialize(aRange)
|
16
17
|
@range = Lexical::TokenRange.new(aRange)
|
17
18
|
end
|
18
|
-
|
19
|
-
# Return the origin, that is, the index of the
|
19
|
+
|
20
|
+
# Return the origin, that is, the index of the
|
20
21
|
# first token matched by this node.
|
21
22
|
# @return [Integer]
|
22
|
-
def origin
|
23
|
-
|
24
|
-
end
|
23
|
+
def origin
|
24
|
+
range.low
|
25
|
+
end
|
25
26
|
end # class
|
26
27
|
end # module
|
27
28
|
end # module
|
data/lib/rley/sppf/token_node.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'leaf_node'
|
2
4
|
|
3
5
|
module Rley # This module is used as a namespace
|
@@ -23,14 +25,14 @@ module Rley # This module is used as a namespace
|
|
23
25
|
# @param indentation [Integer]
|
24
26
|
# @return [String]
|
25
27
|
def to_string(indentation)
|
26
|
-
|
28
|
+
"#{token.terminal.name}#{range.to_string(indentation)}"
|
27
29
|
end
|
28
|
-
|
30
|
+
|
29
31
|
# Part of the 'visitee' role in Visitor design pattern.
|
30
32
|
# @param aVisitor[ParseTreeVisitor] the visitor
|
31
33
|
def accept(aVisitor)
|
32
34
|
aVisitor.visit_terminal(self)
|
33
|
-
end
|
35
|
+
end
|
34
36
|
end # class
|
35
37
|
end # module
|
36
38
|
end # module
|