rley 0.7.03 → 0.7.08
Sign up to get free protection for your applications and to get access to all the features.
- 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
|