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_rep_creator'
|
2
4
|
require_relative 'parse_forest_builder'
|
3
5
|
|
@@ -13,13 +15,13 @@ module Rley # This module is used as a namespace
|
|
13
15
|
def builder(aParseResult, _builder = nil)
|
14
16
|
ParseForestBuilder.new(aParseResult.tokens)
|
15
17
|
end
|
16
|
-
|
18
|
+
|
17
19
|
# When an end vertex is re-visited then jump
|
18
20
|
# its corresponding start vertex. This behaviour
|
19
21
|
# makes sense for sharing nodes.
|
20
|
-
def jump_to_start
|
22
|
+
def jump_to_start
|
21
23
|
true
|
22
|
-
end
|
24
|
+
end
|
23
25
|
end # class
|
24
26
|
end # module
|
25
27
|
end # module
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative '../parser/parse_walker_factory'
|
2
4
|
|
3
5
|
module Rley # This module is used as a namespace
|
@@ -5,18 +7,18 @@ module Rley # This module is used as a namespace
|
|
5
7
|
# Utility class that helps to create a representation of a parse from
|
6
8
|
# a given Parsing object.
|
7
9
|
class ParseRepCreator
|
8
|
-
# @return [Rley::Parser::GFGParsing]
|
10
|
+
# @return [Rley::Parser::GFGParsing]
|
9
11
|
# Link to Parsing object (= results of recognizer)
|
10
12
|
attr_reader(:parsing)
|
11
|
-
|
13
|
+
|
12
14
|
# Constructor. Creates and initialize a ParseRepCreator instance.
|
13
15
|
# @return [ParseRepCreator]
|
14
16
|
def initialize(aParsingResult)
|
15
17
|
@parsing = aParsingResult
|
16
|
-
end
|
17
|
-
|
18
|
+
end
|
19
|
+
|
18
20
|
# Factory method that produces the representation of the parse.
|
19
|
-
# @return [Rley::PTree::ParseTree, Rley::SPPF::ParseForest]
|
21
|
+
# @return [Rley::PTree::ParseTree, Rley::SPPF::ParseForest]
|
20
22
|
# The parse representation.
|
21
23
|
def create(aBuilder = nil)
|
22
24
|
a_walker = walker(parsing)
|
@@ -30,15 +32,20 @@ module Rley # This module is used as a namespace
|
|
30
32
|
end
|
31
33
|
rescue StopIteration
|
32
34
|
# Do nothing: gobble the exception
|
35
|
+
rescue StandardError => e
|
36
|
+
if e.message =~ /^Ambiguous/
|
37
|
+
$stderr.puts parsing
|
38
|
+
end
|
39
|
+
raise e
|
33
40
|
end
|
34
|
-
|
41
|
+
|
35
42
|
a_builder.done!
|
36
43
|
|
37
|
-
|
44
|
+
a_builder.result
|
38
45
|
end
|
39
|
-
|
46
|
+
|
40
47
|
private
|
41
|
-
|
48
|
+
|
42
49
|
# Create a Parsing walker, that is, an object
|
43
50
|
# that will iterate over the relevant nodes (= parsing entries)
|
44
51
|
# of a GFGParsing
|
@@ -51,13 +58,11 @@ module Rley # This module is used as a namespace
|
|
51
58
|
|
52
59
|
# By default, when a end vertex is re-visited don't jump
|
53
60
|
# its corresponding start vertex.
|
54
|
-
def jump_to_start
|
61
|
+
def jump_to_start
|
55
62
|
false
|
56
63
|
end
|
57
|
-
|
58
64
|
end # class
|
59
65
|
end # module
|
60
66
|
end # module
|
61
67
|
|
62
|
-
# End of file
|
63
|
-
|
68
|
+
# End of file
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative '../lexical/token_range'
|
2
4
|
require_relative '../syntax/terminal'
|
3
5
|
require_relative '../syntax/non_terminal'
|
@@ -24,7 +26,7 @@ module Rley # This module is used as a namespace
|
|
24
26
|
end # Struct
|
25
27
|
|
26
28
|
|
27
|
-
# The purpose of a ParseTreeBuilder is to build piece by piece
|
29
|
+
# The purpose of a ParseTreeBuilder is to build piece by piece
|
28
30
|
# a parse tree from a sequence of input tokens and
|
29
31
|
# visit events produced by walking over a GFGParsing object.
|
30
32
|
# Uses the Builder GoF pattern.
|
@@ -46,11 +48,11 @@ module Rley # This module is used as a namespace
|
|
46
48
|
@stack = []
|
47
49
|
@dummy_node = Object.new.freeze
|
48
50
|
end
|
49
|
-
|
51
|
+
|
50
52
|
# Notify the builder that the parse tree construction is complete.
|
51
|
-
def done!
|
53
|
+
def done!
|
52
54
|
result.done!
|
53
|
-
end
|
55
|
+
end
|
54
56
|
|
55
57
|
# Receive events resulting from a visit of GFGParsing object.
|
56
58
|
# These events are produced by a specialized Enumerator created
|
@@ -76,23 +78,21 @@ module Rley # This module is used as a namespace
|
|
76
78
|
protected
|
77
79
|
|
78
80
|
# Return the stack
|
79
|
-
|
80
|
-
@stack
|
81
|
-
end
|
81
|
+
attr_reader(:stack)
|
82
82
|
|
83
83
|
# Overriding method.
|
84
84
|
# Create a parse tree object with given
|
85
85
|
# node as root node.
|
86
86
|
def create_tree(aRootNode)
|
87
87
|
raise StandardError, 'Root node of parse tree is nil!' if aRootNode.nil?
|
88
|
-
|
88
|
+
|
89
89
|
return Rley::PTree::ParseTree.new(aRootNode)
|
90
|
-
end
|
90
|
+
end
|
91
91
|
|
92
92
|
private
|
93
93
|
|
94
94
|
# Return the top of stack element.
|
95
|
-
def tos
|
95
|
+
def tos
|
96
96
|
@stack.last
|
97
97
|
end
|
98
98
|
|
@@ -134,7 +134,7 @@ module Rley # This module is used as a namespace
|
|
134
134
|
case anEvent
|
135
135
|
when :visit, :revisit
|
136
136
|
dot_pos = anEntry.vertex.dotted_item.position
|
137
|
-
if dot_pos.zero? || dot_pos
|
137
|
+
if dot_pos.zero? || dot_pos.negative?
|
138
138
|
# Check for pattern: N => alpha* .
|
139
139
|
process_exit_entry(anEntry, anIndex) if anEntry.exit_entry?
|
140
140
|
|
@@ -207,7 +207,7 @@ module Rley # This module is used as a namespace
|
|
207
207
|
# @param anEntry [ParseEntry] The entry being visited
|
208
208
|
def terminal_before_dot?(anEntry)
|
209
209
|
prev_symbol = anEntry.prev_symbol
|
210
|
-
|
210
|
+
prev_symbol&.terminal?
|
211
211
|
end
|
212
212
|
|
213
213
|
# A terminal symbol was detected at left of dot.
|
@@ -239,7 +239,7 @@ module Rley # This module is used as a namespace
|
|
239
239
|
# array at that position.
|
240
240
|
# If the position is nil, then the node will be placed at the position of
|
241
241
|
# the rightmost nil element in children array.
|
242
|
-
def place_TOS_child(aNode, aRHSPos)
|
242
|
+
def place_TOS_child(aNode, aRHSPos)
|
243
243
|
if aRHSPos.nil?
|
244
244
|
# Retrieve index of most rightmost nil child...
|
245
245
|
pos = tos.children.rindex { |child| child == @dummy_node }
|
@@ -247,7 +247,7 @@ module Rley # This module is used as a namespace
|
|
247
247
|
else
|
248
248
|
pos = aRHSPos
|
249
249
|
end
|
250
|
-
|
250
|
+
|
251
251
|
tos.children[pos] = aNode
|
252
252
|
end
|
253
253
|
|
@@ -260,7 +260,7 @@ module Rley # This module is used as a namespace
|
|
260
260
|
non_terminal = anEntry.vertex.lhs
|
261
261
|
end
|
262
262
|
|
263
|
-
|
263
|
+
non_terminal
|
264
264
|
end
|
265
265
|
end # class
|
266
266
|
end # module
|
@@ -1,25 +1,27 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require_relative '
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
class
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
end #
|
24
|
-
|
25
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'parse_rep_creator'
|
4
|
+
# require_relative 'parse_tree_builder' # TODO remove this line
|
5
|
+
require_relative 'cst_builder'
|
6
|
+
|
7
|
+
module Rley # This module is used as a namespace
|
8
|
+
module ParseRep # This module is used as a namespace
|
9
|
+
# Utility class that helps to create a ParseTree from
|
10
|
+
# a given Parsing object.
|
11
|
+
class ParseTreeFactory < ParseRepCreator
|
12
|
+
protected
|
13
|
+
|
14
|
+
# Create a Builder, that is, an object
|
15
|
+
# that will create piece by piece the forest
|
16
|
+
def builder(aParseResult, aBuilder = nil)
|
17
|
+
if aBuilder
|
18
|
+
aBuilder.new(aParseResult.tokens)
|
19
|
+
else
|
20
|
+
CSTBuilder.new(aParseResult.tokens)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end # class
|
24
|
+
end # module
|
25
|
+
end # module
|
26
|
+
|
27
|
+
# End of file
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Rley # This module is used as a namespace
|
2
4
|
# A visitor class dedicated in the visit of a parse tree.
|
3
5
|
# It combines the Visitor and Observer patterns.
|
@@ -35,7 +37,7 @@ module Rley # This module is used as a namespace
|
|
35
37
|
end
|
36
38
|
|
37
39
|
# The signal to begin the visit of the parse tree.
|
38
|
-
def start
|
40
|
+
def start
|
39
41
|
ptree.accept(self)
|
40
42
|
end
|
41
43
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Rley # Module used as a namespace
|
2
4
|
module Parser # This module is used as a namespace
|
3
5
|
# Abstract class. An instance represents an explanation describing
|
@@ -15,7 +17,7 @@ module Rley # Module used as a namespace
|
|
15
17
|
end
|
16
18
|
|
17
19
|
# @return [String] the result of invoking reason.to_s
|
18
|
-
def message
|
20
|
+
def message
|
19
21
|
return to_s
|
20
22
|
end
|
21
23
|
|
@@ -25,11 +27,10 @@ module Rley # Module used as a namespace
|
|
25
27
|
end
|
26
28
|
end # class
|
27
29
|
|
28
|
-
|
29
30
|
# This parse error occurs when no input for parsing was provided
|
30
31
|
# while the grammar requires some non-empty input.
|
31
32
|
class NoInput < ErrorReason
|
32
|
-
def initialize
|
33
|
+
def initialize
|
33
34
|
super(0)
|
34
35
|
end
|
35
36
|
|
@@ -59,7 +60,7 @@ module Rley # Module used as a namespace
|
|
59
60
|
|
60
61
|
protected
|
61
62
|
|
62
|
-
def position
|
63
|
+
def position
|
63
64
|
return last_token.position if last_token.respond_to?(:position)
|
64
65
|
|
65
66
|
rank + 1
|
@@ -68,13 +69,13 @@ module Rley # Module used as a namespace
|
|
68
69
|
# Emit a text explaining the expected terminal symbols
|
69
70
|
def expectations
|
70
71
|
term_names = expected_terminals.map(&:name)
|
71
|
-
explain = 'Expected one '
|
72
|
+
explain = +'Expected one '
|
72
73
|
explain << if expected_terminals.size > 1
|
73
74
|
"of: ['#{term_names.join("', '")}']"
|
74
75
|
else
|
75
76
|
"'#{term_names[0]}'"
|
76
77
|
end
|
77
|
-
|
78
|
+
explain
|
78
79
|
end
|
79
80
|
end # class
|
80
81
|
|
@@ -83,7 +84,7 @@ module Rley # Module used as a namespace
|
|
83
84
|
class UnexpectedToken < ExpectationNotMet
|
84
85
|
# Returns the reason's message.
|
85
86
|
def to_s
|
86
|
-
err_msg = "Syntax error at or near token #{position} "
|
87
|
+
err_msg = +"Syntax error at or near token #{position} "
|
87
88
|
err_msg << ">>>#{last_token.lexeme}<<<\n"
|
88
89
|
err_msg << expectations
|
89
90
|
err_msg << ", found a '#{last_token.terminal}' instead."
|
@@ -97,7 +98,7 @@ module Rley # Module used as a namespace
|
|
97
98
|
class PrematureInputEnd < ExpectationNotMet
|
98
99
|
# Returns the reason's message.
|
99
100
|
def to_s
|
100
|
-
err_msg = "Premature end of input after '#{last_token.lexeme}'"
|
101
|
+
err_msg = +"Premature end of input after '#{last_token.lexeme}'"
|
101
102
|
err_msg << " at position #{position}\n"
|
102
103
|
err_msg << "#{expectations}."
|
103
104
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'parse_entry'
|
2
4
|
require_relative 'parse_entry_set'
|
3
5
|
|
@@ -14,32 +16,30 @@ module Rley # This module is used as a namespace
|
|
14
16
|
|
15
17
|
# @param aGFGraph [GFG::GrmFlowGraph] The GFG for the grammar in use.
|
16
18
|
def initialize(aGFGraph)
|
17
|
-
@sets = [
|
19
|
+
@sets = [ParseEntrySet.new]
|
18
20
|
push_entry(aGFGraph.start_vertex, 0, 0, :start_rule)
|
19
21
|
end
|
20
22
|
|
21
23
|
# @return [Syntax::NonTerminal] the start symbol of the grammar.
|
22
|
-
def start_symbol
|
23
|
-
|
24
|
+
def start_symbol
|
25
|
+
sets.first.entries[0].vertex.non_terminal
|
24
26
|
end
|
25
27
|
|
26
28
|
# @param index [Integer]
|
27
29
|
# @return [ParseEntrySet] Access the entry set at given position.
|
28
30
|
def [](index)
|
29
|
-
|
31
|
+
sets[index]
|
30
32
|
end
|
31
33
|
|
32
34
|
# Return the index value of the last non-empty entry set.
|
33
35
|
# @return [Integer]
|
34
|
-
def last_index
|
36
|
+
def last_index
|
35
37
|
first_empty = sets.find_index(&:empty?)
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
return index
|
38
|
+
if first_empty.nil?
|
39
|
+
sets.size - 1
|
40
|
+
else
|
41
|
+
first_empty.zero? ? 0 : first_empty - 1
|
42
|
+
end
|
43
43
|
end
|
44
44
|
|
45
45
|
# Push a parse entry for the chart entry with given index
|
@@ -55,23 +55,21 @@ module Rley # This module is used as a namespace
|
|
55
55
|
if anIndex == sets.size
|
56
56
|
err_msg = "Internal error: unexpected push reason #{reason}"
|
57
57
|
raise StandardError, err_msg if reason != :scan_rule
|
58
|
-
|
59
|
-
add_entry_set
|
60
|
-
end
|
61
|
-
pushed = self[anIndex].push_entry(new_entry)
|
62
58
|
|
63
|
-
|
59
|
+
add_entry_set
|
60
|
+
end
|
61
|
+
self[anIndex].push_entry(new_entry)
|
64
62
|
end
|
65
63
|
|
66
64
|
# Retrieve the first parse entry added to this chart
|
67
65
|
# @return [ParseEntry]
|
68
|
-
def initial_entry
|
69
|
-
|
66
|
+
def initial_entry
|
67
|
+
sets[0].first
|
70
68
|
end
|
71
69
|
|
72
70
|
# Retrieve the entry that corresponds to a complete and successful parse
|
73
71
|
# @return [ParseEntry]
|
74
|
-
def accepting_entry
|
72
|
+
def accepting_entry
|
75
73
|
# Success can be detected as follows:
|
76
74
|
# The last chart entry set has at least one complete parse entry
|
77
75
|
# for the start symbol with an origin == 0
|
@@ -91,12 +89,46 @@ module Rley # This module is used as a namespace
|
|
91
89
|
entry.origin.zero? && entry.vertex.non_terminal == start_symbol
|
92
90
|
end
|
93
91
|
|
94
|
-
|
92
|
+
success_entries.first
|
93
|
+
end
|
94
|
+
|
95
|
+
# @return [Integer] The number of states.
|
96
|
+
def count_states
|
97
|
+
sets.size
|
98
|
+
end
|
99
|
+
|
100
|
+
# @return [Integer] The total number of entries.
|
101
|
+
def count_entries
|
102
|
+
# rubocop: disable Lint/UselessAssignment
|
103
|
+
sets.reduce(0) do |sub_result, a_set|
|
104
|
+
sub_result += a_set.size
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# @return [Integer] The total number of edges.
|
109
|
+
def count_edges
|
110
|
+
sets.reduce(0) do |sub_result, a_set|
|
111
|
+
sub_result += a_set.count_edges
|
112
|
+
end
|
113
|
+
end
|
114
|
+
# rubocop: enable Lint/UselessAssignment
|
115
|
+
|
116
|
+
# @ return [String] A human-readable representation of the chart.
|
117
|
+
def to_s
|
118
|
+
result = +''
|
119
|
+
sets.each_with_index do |a_set, i|
|
120
|
+
result << "State[#{i}]\n"
|
121
|
+
a_set.entries.each do |item|
|
122
|
+
result << " #{item}\n"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
result
|
95
127
|
end
|
96
128
|
|
97
129
|
private
|
98
130
|
|
99
|
-
def add_entry_set
|
131
|
+
def add_entry_set
|
100
132
|
@sets << ParseEntrySet.new
|
101
133
|
end
|
102
134
|
end # class
|