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
data/lib/rley/formatter/json.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'base_formatter'
|
2
4
|
|
3
5
|
|
@@ -92,11 +94,11 @@ module Rley # This module is used as a namespace
|
|
92
94
|
|
93
95
|
private
|
94
96
|
|
95
|
-
def indent
|
97
|
+
def indent
|
96
98
|
@indentation += 1
|
97
99
|
end
|
98
100
|
|
99
|
-
def dedent
|
101
|
+
def dedent
|
100
102
|
@indentation -= 1
|
101
103
|
end
|
102
104
|
|
data/lib/rley/gfg/call_edge.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'edge'
|
2
4
|
|
3
5
|
module Rley # This module is used as a namespace
|
@@ -14,7 +16,7 @@ module Rley # This module is used as a namespace
|
|
14
16
|
# Pre-condition: theSuccessor is an StartVertex
|
15
17
|
def initialize(thePredecessor, theSuccessor)
|
16
18
|
super(thePredecessor, theSuccessor)
|
17
|
-
do_set_key(thePredecessor, theSuccessor)
|
19
|
+
do_set_key(thePredecessor, theSuccessor)
|
18
20
|
end
|
19
21
|
|
20
22
|
private
|
data/lib/rley/gfg/edge.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Rley # This module is used as a namespace
|
2
4
|
module GFG # This module is used as a namespace
|
3
5
|
# Abstract class. Represents an edge in a grammar flow graph.
|
@@ -12,18 +14,18 @@ module Rley # This module is used as a namespace
|
|
12
14
|
# @param theSuccessor [Vertex]
|
13
15
|
def initialize(thePredecessor, theSuccessor)
|
14
16
|
@successor = theSuccessor
|
15
|
-
thePredecessor
|
17
|
+
thePredecessor&.add_edge(self)
|
16
18
|
end
|
17
19
|
|
18
20
|
# @return [String]
|
19
|
-
def to_s
|
21
|
+
def to_s
|
20
22
|
" --> #{successor.label}"
|
21
23
|
end
|
22
|
-
|
23
|
-
# Returns a string containing a human-readable representation of the
|
24
|
+
|
25
|
+
# Returns a string containing a human-readable representation of the
|
24
26
|
# production.
|
25
27
|
# @return [String]
|
26
|
-
def inspect
|
28
|
+
def inspect
|
27
29
|
to_s
|
28
30
|
end
|
29
31
|
end # class
|
data/lib/rley/gfg/end_vertex.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'non_terminal_vertex'
|
2
4
|
|
3
5
|
module Rley # This module is used as a namespace
|
@@ -8,12 +10,8 @@ module Rley # This module is used as a namespace
|
|
8
10
|
# Responsibilities (in addition to inherited ones):
|
9
11
|
# - Know its related non-terminal symbol
|
10
12
|
class EndVertex < NonTerminalVertex
|
11
|
-
def
|
12
|
-
|
13
|
-
end
|
14
|
-
|
15
|
-
def label()
|
16
|
-
return "#{non_terminal}."
|
13
|
+
def label
|
14
|
+
"#{non_terminal}."
|
17
15
|
end
|
18
16
|
end # class
|
19
17
|
end # module
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'edge'
|
2
4
|
|
3
5
|
module Rley # This module is used as a namespace
|
@@ -7,12 +9,8 @@ module Rley # This module is used as a namespace
|
|
7
9
|
# Responsibilities:
|
8
10
|
# - To know the successor vertex
|
9
11
|
class EpsilonEdge < Edge
|
10
|
-
# The destination vertex of the edge
|
12
|
+
# The destination vertex of the edge.
|
11
13
|
attr_reader :successor
|
12
|
-
|
13
|
-
def initialize(thePredecessor, theSuccessor)
|
14
|
-
super(thePredecessor, theSuccessor)
|
15
|
-
end
|
16
14
|
end # class
|
17
15
|
end # module
|
18
16
|
end # module
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'set'
|
2
4
|
require_relative 'start_vertex'
|
3
5
|
require_relative 'end_vertex'
|
@@ -11,26 +13,26 @@ require_relative 'shortcut_edge'
|
|
11
13
|
module Rley # This module is used as a namespace
|
12
14
|
module GFG # This module is used as a namespace
|
13
15
|
# A Grammar Flow Graph (GFG) represents the parsing states of productions
|
14
|
-
# rules from a context-free grammar. This representation is based on a
|
15
|
-
# directed graph structure. The parsing process can then be re-formulated
|
16
|
+
# rules from a context-free grammar. This representation is based on a
|
17
|
+
# directed graph structure. The parsing process can then be re-formulated
|
16
18
|
# as a path problem in the graph. The theory behind GFGs can be found in
|
17
19
|
# papers. The first article on GFG can be found here:
|
18
20
|
# https://apps.cs.utexas.edu/tech_reports/reports/tr/TR-2102.pdf
|
19
|
-
# There are three types of vertex in a GFG:
|
21
|
+
# There are three types of vertex in a GFG:
|
20
22
|
# start vertex, end vertex and item vertex.
|
21
23
|
# For each non-terminal symbol N of the grammar, there is:
|
22
24
|
# a start vertex with label '.N'
|
23
25
|
# an end vertex with label 'N.'
|
24
26
|
# For each production rule of the grammar:
|
25
27
|
# N => s1 s2 s3 (...) sk
|
26
|
-
# I.e. a rule with k grammar symbols in its right-handed side.
|
28
|
+
# I.e. a rule with k grammar symbols in its right-handed side.
|
27
29
|
# For such a rule there will be k + 1 item vertices. By convention,
|
28
30
|
# the first item vertex is labelled as 'N => . s1 s2 s3 (...) sk'
|
29
31
|
# the second item vertex is labelled as 'N => s1 . s2 s3 (...) sk'
|
30
32
|
# the third item vertex is labelled as 'N => s1 s2 . s3 (...) sk'
|
31
33
|
# and so on. In other words, the labels are obtained by moving a dot
|
32
|
-
# in successive positions in the rhs. The dot represents the
|
33
|
-
# parse progress for the production rule. Symbols on the left of the
|
34
|
+
# in successive positions in the rhs. The dot represents the
|
35
|
+
# parse progress for the production rule. Symbols on the left of the
|
34
36
|
# dot represent the symbols that were successfully matched in the input.
|
35
37
|
# A GFG has three types of directed edges linking the vertices.
|
36
38
|
# call edge, return edge and scan edge.
|
@@ -58,24 +60,24 @@ module Rley # This module is used as a namespace
|
|
58
60
|
|
59
61
|
build_graph(theDottedItems)
|
60
62
|
end
|
61
|
-
|
62
|
-
# Returns a string containing a human-readable representation of the
|
63
|
+
|
64
|
+
# Returns a string containing a human-readable representation of the
|
63
65
|
# production.
|
64
66
|
# @return [String]
|
65
|
-
def inspect
|
66
|
-
result = "#<#{self.class.name}:#{object_id}"
|
67
|
+
def inspect
|
68
|
+
result = +"#<#{self.class.name}:#{object_id}"
|
67
69
|
result << ' @vertices=['
|
68
70
|
list = vertices.map { |v| "#<#{v.selfie}>" }
|
69
71
|
result << list.join(', ')
|
70
72
|
result << '] '
|
71
73
|
edges = []
|
72
|
-
vertices.each do |v|
|
74
|
+
vertices.each do |v|
|
73
75
|
edges << v.edges do |e|
|
74
76
|
result << "#{v.object_id} #{e.inspect}"
|
75
77
|
end
|
76
78
|
end
|
77
79
|
result << "edges=[#{edges.join(",\n ")}]>"
|
78
|
-
|
80
|
+
result
|
79
81
|
end
|
80
82
|
|
81
83
|
# Retrieve the vertex with given vertex label.
|
@@ -90,7 +92,7 @@ module Rley # This module is used as a namespace
|
|
90
92
|
# If one wants to remove useless rules, then do first:
|
91
93
|
# elimination of non-generating symbols
|
92
94
|
# then elimination of unreachable symbols
|
93
|
-
def diagnose
|
95
|
+
def diagnose
|
94
96
|
mark_unreachable_symbols
|
95
97
|
end
|
96
98
|
|
@@ -119,6 +121,7 @@ module Rley # This module is used as a namespace
|
|
119
121
|
# @param aStartVertex [StartVertex] the depth-first traversal begins
|
120
122
|
# from here
|
121
123
|
# @param _visitAction [Proc] block called when a new graph vertex is found
|
124
|
+
# rubocop: disable Lint/Loop
|
122
125
|
def traverse_df(aStartVertex, &_visitAction)
|
123
126
|
visited = Set.new
|
124
127
|
stack = []
|
@@ -127,13 +130,13 @@ module Rley # This module is used as a namespace
|
|
127
130
|
|
128
131
|
begin
|
129
132
|
# print_vertex( 'Traversing', visitee)
|
130
|
-
|
133
|
+
|
131
134
|
first_time = !visited.include?(visitee)
|
132
135
|
if first_time
|
133
136
|
yield(visitee)
|
134
137
|
visited << visitee
|
135
|
-
end
|
136
|
-
|
138
|
+
end
|
139
|
+
|
137
140
|
case visitee
|
138
141
|
when Rley::GFG::StartVertex
|
139
142
|
if first_time
|
@@ -153,12 +156,12 @@ module Rley # This module is used as a namespace
|
|
153
156
|
if stack.last.done?
|
154
157
|
popped = stack.pop
|
155
158
|
break if stack.empty?
|
156
|
-
|
159
|
+
|
157
160
|
# puts "Popped!"
|
158
161
|
return_key = popped.in_edge.key.sub(/^CALL/, 'RET')
|
159
162
|
curr_edge = visitee.edges.find { |e| e.key == return_key }
|
160
163
|
else
|
161
|
-
curr_edge = stack.last.next_edge
|
164
|
+
curr_edge = stack.last.next_edge
|
162
165
|
end
|
163
166
|
|
164
167
|
else
|
@@ -171,6 +174,7 @@ module Rley # This module is used as a namespace
|
|
171
174
|
last_one = end_vertex_for[aStartVertex.non_terminal]
|
172
175
|
yield(last_one) unless visited.include?(last_one)
|
173
176
|
end
|
177
|
+
# rubocop: enable Lint/Loop
|
174
178
|
|
175
179
|
private
|
176
180
|
|
@@ -181,16 +185,16 @@ module Rley # This module is used as a namespace
|
|
181
185
|
@start_vertex = aVertex if vertices.empty?
|
182
186
|
vertices << aVertex
|
183
187
|
end
|
184
|
-
|
188
|
+
|
185
189
|
# For debugging purposes
|
186
190
|
def print_vertex(aText, aVertex)
|
187
|
-
print aText
|
191
|
+
print "#{aText} "
|
188
192
|
if aVertex.kind_of?(NonTerminalVertex)
|
189
193
|
puts "#{aVertex.class} #{aVertex.non_terminal.name}"
|
190
194
|
else
|
191
195
|
p(aVertex.label)
|
192
|
-
end
|
193
|
-
end
|
196
|
+
end
|
197
|
+
end
|
194
198
|
|
195
199
|
def build_graph(theDottedItems)
|
196
200
|
build_all_starts_ends(theDottedItems)
|
@@ -198,7 +202,7 @@ module Rley # This module is used as a namespace
|
|
198
202
|
curr_prod = nil
|
199
203
|
theDottedItems.each_with_index do |d_item, index_item|
|
200
204
|
next unless curr_prod.nil? || curr_prod != d_item.production
|
201
|
-
|
205
|
+
|
202
206
|
# Another production found...
|
203
207
|
curr_prod = d_item.production
|
204
208
|
if curr_prod.empty?
|
@@ -266,6 +270,7 @@ module Rley # This module is used as a namespace
|
|
266
270
|
# add a shortcut edge:
|
267
271
|
# ( N => α[1] .A α[n] ) -> ( N => α[1] A. α[n] )
|
268
272
|
def augment_graph(theDottedItems, firstItemPos)
|
273
|
+
# rubocop: disable Lint/RedundantSafeNavigation
|
269
274
|
production = theDottedItems[firstItemPos].production
|
270
275
|
max_index = production.rhs.size + 1
|
271
276
|
prev_vertex = nil
|
@@ -290,12 +295,13 @@ module Rley # This module is used as a namespace
|
|
290
295
|
end
|
291
296
|
|
292
297
|
prev_symbol = current_item.prev_symbol
|
293
|
-
if prev_symbol
|
298
|
+
if prev_symbol&.kind_of?(Syntax::NonTerminal)
|
294
299
|
build_shortcut_edge(prev_vertex, new_vertex)
|
295
300
|
end
|
296
301
|
prev_vertex = new_vertex
|
297
302
|
end
|
298
303
|
end
|
304
|
+
# rubocop: enable Lint/RedundantSafeNavigation
|
299
305
|
|
300
306
|
# Create an entry edge for the given vertex
|
301
307
|
def build_entry_edge(theVertex)
|
@@ -357,7 +363,7 @@ module Rley # This module is used as a namespace
|
|
357
363
|
# Mark non-terminal symbols that cannot be derived from the start symbol.
|
358
364
|
# In a GFG, a non-terminal symbol N is unreachable if there is no path
|
359
365
|
# from the start symbol to the start node .N
|
360
|
-
def mark_unreachable_symbols
|
366
|
+
def mark_unreachable_symbols
|
361
367
|
# Mark all non-terminals as unreachable
|
362
368
|
start_vertex_for.each_value do |a_vertex|
|
363
369
|
a_vertex.non_terminal.unreachable = true
|
data/lib/rley/gfg/item_vertex.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative '../syntax/non_terminal'
|
2
4
|
require_relative 'vertex'
|
3
5
|
|
@@ -30,53 +32,41 @@ module Rley # This module is used as a namespace
|
|
30
32
|
def shortcut=(aShortcut)
|
31
33
|
unless aShortcut.kind_of?(ShortcutEdge)
|
32
34
|
raise StandardError, 'Invalid shortcut argument'
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
=begin
|
37
|
-
unless next_symbol && next_symbol.kind_of?(Syntax::NonTerminal)
|
38
|
-
raise StandardError, 'Invalid shortcut usage'
|
39
35
|
end
|
40
36
|
|
41
|
-
shortcut_d_item = aShortcut.successor.dotted_item
|
42
|
-
unless (dotted_item.production == shortcut_d_item.production) &&
|
43
|
-
(dotted_item.position == shortcut_d_item.prev_position)
|
44
|
-
raise StandardError, 'Shortcut refers to wrong vertex'
|
45
|
-
end
|
46
|
-
=end
|
47
37
|
@shortcut = aShortcut
|
48
38
|
end
|
49
39
|
|
50
40
|
# The label of this vertex.
|
51
41
|
# It is the same as the label of the corresponding dotted item.
|
52
42
|
# @return [String] Label for this vertex
|
53
|
-
def label
|
54
|
-
|
43
|
+
def label
|
44
|
+
dotted_item.to_s
|
55
45
|
end
|
56
46
|
|
57
47
|
# Returns true if the dotted item has a dot at the end of the production.
|
58
48
|
# @return [Boolean]
|
59
|
-
def complete?
|
60
|
-
|
49
|
+
def complete?
|
50
|
+
dotted_item.reduce_item?
|
61
51
|
end
|
62
52
|
|
63
53
|
# Return the symbol before the dot.
|
64
54
|
# @return [Syntax::GrmSymbol, NilClass] Previous symbol otherwise nil.
|
65
|
-
def prev_symbol
|
66
|
-
|
55
|
+
def prev_symbol
|
56
|
+
dotted_item.prev_symbol
|
67
57
|
end
|
68
58
|
|
69
59
|
# Return the symbol after the dot.
|
70
60
|
# @return [Syntax::GrmSymbol, NilClass] Next grammar symbol otherwise nil.
|
71
|
-
def next_symbol
|
72
|
-
|
61
|
+
def next_symbol
|
62
|
+
@next_symbol ||= dotted_item.next_symbol
|
73
63
|
end
|
74
64
|
|
75
65
|
# Return the non-terminal symbol at the left-hand side of the production
|
76
66
|
# @return [Syntax::GrmSymbol]
|
77
67
|
# The non-terminal symbol at left side of production.
|
78
|
-
def lhs
|
79
|
-
|
68
|
+
def lhs
|
69
|
+
dotted_item.lhs
|
80
70
|
end
|
81
71
|
end # class
|
82
72
|
end # module
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'vertex'
|
2
4
|
|
3
5
|
module Rley # This module is used as a namespace
|
4
6
|
module GFG # This module is used as a namespace
|
5
7
|
# Abstract class.
|
6
|
-
# Represents a specialized vertex in a grammar flow graph
|
8
|
+
# Represents a specialized vertex in a grammar flow graph
|
7
9
|
# that is associated to a given non-terminal symbol and
|
8
10
|
# that may have in-degree or out-degree > 1
|
9
11
|
# Responsibilities (in addition to inherited ones):
|
@@ -12,20 +14,20 @@ module Rley # This module is used as a namespace
|
|
12
14
|
# The non-terminal symbol associated to the vertex
|
13
15
|
# @return [Syntax::NonTerminal]
|
14
16
|
attr_reader :non_terminal
|
15
|
-
|
17
|
+
|
16
18
|
# Constructor to specialize in subclasses.
|
17
19
|
# @param aNonTerminal [Syntax::NonTerminal]
|
18
20
|
def initialize(aNonTerminal)
|
19
21
|
super()
|
20
22
|
@non_terminal = aNonTerminal
|
21
23
|
end
|
22
|
-
|
24
|
+
|
23
25
|
protected
|
24
26
|
|
25
27
|
# Validation method for adding an outgoing edge to the vertex.
|
26
28
|
# A start vertex may accept an indegree and outdegree greater than one
|
27
29
|
def check_add_edge(anEdge)
|
28
|
-
|
30
|
+
anEdge
|
29
31
|
end
|
30
32
|
end # class
|
31
33
|
end # module
|
data/lib/rley/gfg/return_edge.rb
CHANGED
data/lib/rley/gfg/scan_edge.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'edge'
|
2
4
|
|
3
5
|
module Rley # This module is used as a namespace
|
@@ -15,7 +17,7 @@ module Rley # This module is used as a namespace
|
|
15
17
|
@terminal = aTerminal
|
16
18
|
end
|
17
19
|
|
18
|
-
def to_s
|
20
|
+
def to_s
|
19
21
|
" -#{terminal}-> #{successor.label}"
|
20
22
|
end
|
21
23
|
end # class
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'edge'
|
2
4
|
|
3
5
|
module Rley # This module is used as a namespace
|
@@ -10,12 +12,12 @@ module Rley # This module is used as a namespace
|
|
10
12
|
attr_reader :nonterminal
|
11
13
|
|
12
14
|
def initialize(thePredecessor, theSuccessor)
|
13
|
-
|
15
|
+
super(nil, theSuccessor)
|
14
16
|
@nonterminal = thePredecessor.next_symbol
|
15
17
|
thePredecessor.shortcut = self
|
16
18
|
end
|
17
19
|
|
18
|
-
def to_s
|
20
|
+
def to_s
|
19
21
|
" -#{nonterminal}-> #{successor.label}"
|
20
22
|
end
|
21
23
|
end # class
|
@@ -1,21 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'non_terminal_vertex'
|
2
4
|
|
3
5
|
module Rley # This module is used as a namespace
|
4
6
|
module GFG # This module is used as a namespace
|
5
7
|
# TODO: change definition.
|
6
|
-
# Represents a specialized vertex in a grammar flow graph
|
8
|
+
# Represents a specialized vertex in a grammar flow graph
|
7
9
|
# that is associated to a given non-terminal symbol.
|
8
10
|
# Responsibilities (in addition to inherited ones):
|
9
11
|
# - Know its related non-terminal symbol
|
10
12
|
class StartVertex < NonTerminalVertex
|
11
|
-
def initialize(aNonTerminal)
|
12
|
-
super(aNonTerminal)
|
13
|
-
end
|
14
|
-
|
15
13
|
# @return [String]
|
16
|
-
def label
|
17
|
-
|
18
|
-
end
|
14
|
+
def label
|
15
|
+
".#{non_terminal}"
|
16
|
+
end
|
19
17
|
end # class
|
20
18
|
end # module
|
21
19
|
end # module
|