rley 0.2.09 → 0.2.10
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 +8 -8
- data/.rubocop.yml +87 -83
- data/CHANGELOG.md +4 -0
- data/lib/rley/constants.rb +1 -1
- data/lib/rley/parse_tree_visitor.rb +29 -17
- data/lib/rley/parser/chart.rb +1 -1
- data/lib/rley/parser/earley_parser.rb +2 -2
- data/lib/rley/parser/parse_state_tracker.rb +1 -1
- data/lib/rley/parser/parse_tracer.rb +8 -7
- data/lib/rley/parser/parsing.rb +2 -1
- data/lib/rley/parser/state_set.rb +2 -2
- data/lib/rley/ptree/non_terminal_node.rb +1 -3
- data/lib/rley/ptree/parse_tree.rb +8 -0
- data/spec/rley/parse_tree_visitor_spec.rb +2 -2
- data/spec/rley/parser/chart_spec.rb +4 -4
- data/spec/rley/parser/earley_parser_spec.rb +3 -2
- data/spec/rley/parser/parse_tracer_spec.rb +26 -24
- data/spec/rley/parser/parsing_spec.rb +3 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YTA0ZWM0OGY5NTM0ZGJhYTYyMDMyOGEyMjk4Mzc0NTMxOWZkZmMxYw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
OGRhZDdiMzg5ZDA2YTA3YTZiZTBjYWYyOTFkOGJlNTVhNjk5YmVmZg==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NTA0MTBkNzU4ZDdkNmNmOTA5YjBmNTY3Njg4ZDVkZGU5MmMzNzFmZWVlY2Fm
|
10
|
+
YzUzZWI4MzU3NmZjYTBmYWQ0NjQzY2QxZjBlMTZlMGIxODY5ZDQ2NTM0ZDRk
|
11
|
+
NTdjODAxZjViZmU2MThiNDhkNDEzNGI3MjVkMDg3MDI3ZTIwNTU=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NTFiZGZlZWI2NTU0ZjNmMzlhZjVmZTlkNmM3ZTFmZGFhYmNhYjcwNDQ5Zjdi
|
14
|
+
NGRlMjkwZGJjZjMzNDMxOGM3NTIyYTdjNmQzYjQyMGI3ZjdiMDdjMmE5MDkz
|
15
|
+
NzI5ZDRmZTQ1Zjg2YjFjYmVhMTJmNGYxZTViNTQzNTRlNjhiNjI=
|
data/.rubocop.yml
CHANGED
@@ -1,83 +1,87 @@
|
|
1
|
-
AllCops:
|
2
|
-
Exclude:
|
3
|
-
- 'examples/**/*'
|
4
|
-
- 'features/**/*'
|
5
|
-
- 'gems/**/*'
|
6
|
-
- '
|
7
|
-
|
8
|
-
AbcSize:
|
9
|
-
Max:
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
1
|
+
AllCops:
|
2
|
+
Exclude:
|
3
|
+
- 'examples/**/*'
|
4
|
+
- 'features/**/*'
|
5
|
+
- 'gems/**/*'
|
6
|
+
- 'lab/**/*'
|
7
|
+
|
8
|
+
AbcSize:
|
9
|
+
Max: 35
|
10
|
+
|
11
|
+
# This is disabled because some demos use UTF-8
|
12
|
+
AsciiComments:
|
13
|
+
Enabled: false
|
14
|
+
|
15
|
+
Attr:
|
16
|
+
Enabled: false
|
17
|
+
|
18
|
+
BlockComments:
|
19
|
+
Enabled: false
|
20
|
+
|
21
|
+
CaseIndentation:
|
22
|
+
IndentWhenRelativeTo: end
|
23
|
+
IndentOneStep: true
|
24
|
+
|
25
|
+
# Rubocop enforces the use of is_a? instead of kind_of?
|
26
|
+
# Which is contrary to modelling practice.
|
27
|
+
ClassCheck:
|
28
|
+
Enabled: false
|
29
|
+
|
30
|
+
ClassLength:
|
31
|
+
Max: 250
|
32
|
+
CountComments: false
|
33
|
+
|
34
|
+
ConstantName:
|
35
|
+
Enabled: false
|
36
|
+
|
37
|
+
CyclomaticComplexity:
|
38
|
+
Enabled: false
|
39
|
+
|
40
|
+
DefWithParentheses:
|
41
|
+
Enabled: false
|
42
|
+
|
43
|
+
Documentation:
|
44
|
+
Enabled: false
|
45
|
+
|
46
|
+
EmptyLines:
|
47
|
+
Enabled: false
|
48
|
+
|
49
|
+
Encoding:
|
50
|
+
Enabled: false
|
51
|
+
|
52
|
+
IndentationWidth :
|
53
|
+
Enabled: false
|
54
|
+
|
55
|
+
|
56
|
+
# Avoid methods longer than 50 lines of code
|
57
|
+
MethodLength:
|
58
|
+
Max: 50
|
59
|
+
CountComments: false
|
60
|
+
|
61
|
+
# Avoid modules longer than 500 lines of code
|
62
|
+
ModuleLength:
|
63
|
+
Max: 500
|
64
|
+
|
65
|
+
NonNilCheck:
|
66
|
+
Enabled: false
|
67
|
+
|
68
|
+
NumericLiterals:
|
69
|
+
Enabled: false
|
70
|
+
|
71
|
+
PerceivedComplexity:
|
72
|
+
Max: 10
|
73
|
+
|
74
|
+
RaiseArgs:
|
75
|
+
Enabled: false
|
76
|
+
|
77
|
+
RedundantReturn:
|
78
|
+
Enabled: false
|
79
|
+
|
80
|
+
SpaceInsideBrackets:
|
81
|
+
Enabled: false
|
82
|
+
|
83
|
+
TrailingWhitespace:
|
84
|
+
Enabled: false
|
85
|
+
|
86
|
+
VariableName:
|
87
|
+
Enabled: false
|
data/CHANGELOG.md
CHANGED
data/lib/rley/constants.rb
CHANGED
@@ -1,17 +1,22 @@
|
|
1
1
|
module Rley # This module is used as a namespace
|
2
|
-
# A visitor class dedicated in the visit of
|
2
|
+
# A visitor class dedicated in the visit of a parse tree.
|
3
|
+
# It combines the Visitor and Observer patterns.
|
3
4
|
class ParseTreeVisitor
|
4
5
|
# Link to the parse tree to visit
|
5
6
|
attr_reader(:ptree)
|
6
7
|
|
7
8
|
# List of objects that subscribed to the visit event notification.
|
8
9
|
attr_reader(:subscribers)
|
10
|
+
|
11
|
+
# Indicates the kind of tree traversal to perform: :post_order, :pre-order
|
12
|
+
attr_reader(:traversal)
|
9
13
|
|
10
14
|
# Build a visitor for the given ptree.
|
11
15
|
# @param aParseTree [ParseTree] the parse tree to visit.
|
12
|
-
def initialize(aParseTree)
|
16
|
+
def initialize(aParseTree, aTraversalStrategy = :post_order)
|
13
17
|
@ptree = aParseTree
|
14
18
|
@subscribers = []
|
19
|
+
@traversal = aTraversalStrategy
|
15
20
|
end
|
16
21
|
|
17
22
|
public
|
@@ -44,21 +49,15 @@ module Rley # This module is used as a namespace
|
|
44
49
|
|
45
50
|
# Visit event. The visitor is about to visit the given non terminal node.
|
46
51
|
# @param aNonTerminalNode [NonTerminalNode] the node to visit.
|
47
|
-
def
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
broadcast(:before_children, aParentNode, children)
|
57
|
-
|
58
|
-
# Let's proceed with the visit of children
|
59
|
-
children.each { |a_node| a_node.accept(self) }
|
60
|
-
|
61
|
-
broadcast(:after_children, aParentNode, children)
|
52
|
+
def visit_nonterminal(aNonTerminalNode)
|
53
|
+
if @traversal == :post_order
|
54
|
+
broadcast(:before_non_terminal, aNonTerminalNode)
|
55
|
+
traverse_children(aNonTerminalNode)
|
56
|
+
else
|
57
|
+
traverse_children(aNonTerminalNode)
|
58
|
+
broadcast(:before_non_terminal, aNonTerminalNode)
|
59
|
+
end
|
60
|
+
broadcast(:after_non_terminal, aNonTerminalNode)
|
62
61
|
end
|
63
62
|
|
64
63
|
# Visit event. The visitor is visiting the
|
@@ -84,6 +83,19 @@ module Rley # This module is used as a namespace
|
|
84
83
|
end
|
85
84
|
|
86
85
|
private
|
86
|
+
|
87
|
+
# Visit event. The visitor is about to visit the children of a non
|
88
|
+
# terminal node.
|
89
|
+
# @param aParentNode [NonTeminalNode] the (non-terminal) parent node.
|
90
|
+
def traverse_children(aParentNode)
|
91
|
+
children = aParentNode.children
|
92
|
+
broadcast(:before_children, aParentNode, children)
|
93
|
+
|
94
|
+
# Let's proceed with the visit of children
|
95
|
+
children.each { |a_node| a_node.accept(self) }
|
96
|
+
|
97
|
+
broadcast(:after_children, aParentNode, children)
|
98
|
+
end
|
87
99
|
|
88
100
|
# Send a notification to all subscribers.
|
89
101
|
# @param msg [Symbol] event to notify
|
data/lib/rley/parser/chart.rb
CHANGED
@@ -61,7 +61,7 @@ module Rley # This module is used as a namespace
|
|
61
61
|
when :completion
|
62
62
|
tracer.trace_completion(anIndex, new_state)
|
63
63
|
else
|
64
|
-
|
64
|
+
fail NotImplementedError, "Unknown push_state mode #{aReason}"
|
65
65
|
end
|
66
66
|
end
|
67
67
|
end
|
@@ -216,8 +216,8 @@ module Rley # This module is used as a namespace
|
|
216
216
|
else
|
217
217
|
err_msg << ": #{term_names[0]},"
|
218
218
|
end
|
219
|
-
err_msg << " found a '#{aParsing.tokens[pos-1].terminal.name}'
|
220
|
-
fail StandardError, err_msg
|
219
|
+
err_msg << " found a '#{aParsing.tokens[pos - 1].terminal.name}'"
|
220
|
+
fail StandardError, err_msg + ' instead.'
|
221
221
|
end
|
222
222
|
end # class
|
223
223
|
end # module
|
@@ -25,7 +25,7 @@ module Rley # This module is used as a namespace
|
|
25
25
|
|
26
26
|
# Write accessor. Set the given parse state as the current one.
|
27
27
|
def parse_state=(aParseState)
|
28
|
-
fail StandardError,
|
28
|
+
fail StandardError, 'Nil parse state' if aParseState.nil?
|
29
29
|
@parse_state = aParseState
|
30
30
|
processed_states[parse_state] = true
|
31
31
|
end
|
@@ -34,9 +34,9 @@ module Rley # This module is used as a namespace
|
|
34
34
|
def trace_scanning(aStatesetIndex, aParseState)
|
35
35
|
return unless level
|
36
36
|
|
37
|
-
scan_picture = '[' + '-' * (col_width-1) + ']'
|
37
|
+
scan_picture = '[' + '-' * (col_width - 1) + ']'
|
38
38
|
org = OpenStruct.new(origin: aStatesetIndex - 1,
|
39
|
-
|
39
|
+
dotted_rule: aParseState.dotted_rule)
|
40
40
|
trace_diagram(aStatesetIndex, org, scan_picture)
|
41
41
|
end
|
42
42
|
|
@@ -49,7 +49,8 @@ module Rley # This module is used as a namespace
|
|
49
49
|
def trace_completion(aStatesetIndex, aParseState)
|
50
50
|
return unless level
|
51
51
|
|
52
|
-
if aStatesetIndex == lexemes.size && aParseState.origin == 0 &&
|
52
|
+
if aStatesetIndex == lexemes.size && aParseState.origin == 0 &&
|
53
|
+
aParseState.complete?
|
53
54
|
picture = '=' * (col_width * lexemes.size - 1)
|
54
55
|
else
|
55
56
|
count = col_width * (aStatesetIndex - aParseState.origin) - 1
|
@@ -69,14 +70,14 @@ module Rley # This module is used as a namespace
|
|
69
70
|
def emit_heading()
|
70
71
|
longest = lexemes.map(&:length).max
|
71
72
|
@col_width = longest + 3
|
72
|
-
headers = lexemes.map { |l| "#{l.center(col_width-1, ' ')}" }
|
73
|
+
headers = lexemes.map { |l| "#{l.center(col_width - 1, ' ')}" }
|
73
74
|
print_if 1, '|.' + headers.join('.') + ".|\n"
|
74
75
|
end
|
75
76
|
|
76
77
|
def padding(aStatesetIndex, aParseState, aPicture)
|
77
|
-
l_pad_pattern = '.' + ' ' * (col_width-1)
|
78
|
+
l_pad_pattern = '.' + ' ' * (col_width - 1)
|
78
79
|
left_padding = l_pad_pattern * ([0, aParseState.origin].max)
|
79
|
-
r_pad_pattern = ' ' * (col_width-1) + '.'
|
80
|
+
r_pad_pattern = ' ' * (col_width - 1) + '.'
|
80
81
|
right_padding = r_pad_pattern * (lexemes.size - aStatesetIndex)
|
81
82
|
return left_padding + aPicture + right_padding
|
82
83
|
end
|
@@ -97,4 +98,4 @@ module Rley # This module is used as a namespace
|
|
97
98
|
end # module
|
98
99
|
end # module
|
99
100
|
|
100
|
-
# End of file
|
101
|
+
# End of file
|
data/lib/rley/parser/parsing.rb
CHANGED
@@ -41,7 +41,8 @@ module Rley # This module is used as a namespace
|
|
41
41
|
builder = tree_builder(state_tracker.state_set_index)
|
42
42
|
|
43
43
|
loop do
|
44
|
-
|
44
|
+
state_tracker.symbol_on_left
|
45
|
+
# match_symbol = state_tracker.symbol_on_left
|
45
46
|
# puts '--------------------'
|
46
47
|
# puts "Active parse state: #{state_tracker.parse_state}"
|
47
48
|
# puts "Matching symbol: #{match_symbol}"
|
@@ -60,8 +60,8 @@ module Rley # This module is used as a namespace
|
|
60
60
|
return candidate
|
61
61
|
end
|
62
62
|
|
63
|
-
# The list of distinct expected terminal symbols. An expected symbol
|
64
|
-
# left of a dot in a parse state of the parse set.
|
63
|
+
# The list of distinct expected terminal symbols. An expected symbol
|
64
|
+
# is on the left of a dot in a parse state of the parse set.
|
65
65
|
def expected_terminals()
|
66
66
|
expecting_terminals = states.select do |s|
|
67
67
|
s.dotted_rule.next_symbol.kind_of?(Rley::Syntax::Terminal)
|
@@ -32,9 +32,7 @@ module Rley # This module is used as a namespace
|
|
32
32
|
# Part of the 'visitee' role in Visitor design pattern.
|
33
33
|
# @param aVisitor[ParseTreeVisitor] the visitor
|
34
34
|
def accept(aVisitor)
|
35
|
-
aVisitor.
|
36
|
-
aVisitor.visit_children(self)
|
37
|
-
aVisitor.end_visit_nonterminal(self)
|
35
|
+
aVisitor.visit_nonterminal(self)
|
38
36
|
end
|
39
37
|
end # class
|
40
38
|
end # module
|
@@ -3,6 +3,14 @@ require_relative 'non_terminal_node'
|
|
3
3
|
|
4
4
|
module Rley # This module is used as a namespace
|
5
5
|
module PTree # This module is used as a namespace
|
6
|
+
# 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,
|
8
|
+
# a node corresponds to a grammar symbol used during the parsing:
|
9
|
+
# - a leaf node maps to a terminal symbol occurring in
|
10
|
+
# the input, and
|
11
|
+
# - a intermediate node maps to a non-terminal node reduced
|
12
|
+
# during the parse.
|
13
|
+
# The root node corresponds to the main/start symbol of the grammar.
|
6
14
|
class ParseTree
|
7
15
|
# The root node of the tree
|
8
16
|
attr_reader(:root)
|
@@ -128,7 +128,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
128
128
|
it 'should react to the start_visit_nonterminal message' do
|
129
129
|
# Notify subscribers when start the visit of a non-terminal node
|
130
130
|
expect(listener1).to receive(:before_non_terminal).with(nterm_node)
|
131
|
-
subject.
|
131
|
+
subject.visit_nonterminal(nterm_node)
|
132
132
|
end
|
133
133
|
|
134
134
|
it 'should react to the visit_children message' do
|
@@ -139,7 +139,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
139
139
|
expect(listener1).to receive(:before_terminal).with(children[0])
|
140
140
|
expect(listener1).to receive(:after_terminal).with(children[0])
|
141
141
|
expect(listener1).to receive(:after_children).with(nterm_node, children)
|
142
|
-
subject.
|
142
|
+
subject.send(:traverse_children, nterm_node)
|
143
143
|
end
|
144
144
|
|
145
145
|
it 'should react to the end_visit_nonterminal message' do
|
@@ -21,8 +21,8 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
21
21
|
let(:output) { StringIO.new('', 'w') }
|
22
22
|
|
23
23
|
let(:token_seq) do
|
24
|
-
literals =
|
25
|
-
literals.map {|lexeme| Token.new(lexeme, nil)}
|
24
|
+
literals = %w(I saw John with a dog)
|
25
|
+
literals.map { |lexeme| Token.new(lexeme, nil) }
|
26
26
|
end
|
27
27
|
|
28
28
|
let(:sample_tracer) { ParseTracer.new(0, output, token_seq) }
|
@@ -32,7 +32,8 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
32
32
|
subject { Chart.new(dotted_rule, count_token, sample_tracer) }
|
33
33
|
|
34
34
|
it 'should be created with start dotted rule, token count, tracer' do
|
35
|
-
expect { Chart.new(dotted_rule, count_token, sample_tracer) }
|
35
|
+
expect { Chart.new(dotted_rule, count_token, sample_tracer) }
|
36
|
+
.not_to raise_error
|
36
37
|
end
|
37
38
|
|
38
39
|
it 'should have a seed state in first state_set' do
|
@@ -91,7 +92,6 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
91
92
|
|> . . . . . .| [0:0] sentence => A B . C
|
92
93
|
SNIPPET
|
93
94
|
expect(output.string).to eq(expectation)
|
94
|
-
|
95
95
|
end
|
96
96
|
|
97
97
|
it 'should trace parse state pushing' do
|
@@ -233,7 +233,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
233
233
|
$stdout = StringIO.new('', 'w')
|
234
234
|
|
235
235
|
trace_level = 1
|
236
|
-
|
236
|
+
subject.parse(grm1_tokens, trace_level)
|
237
237
|
expectations = <<-SNIPPET
|
238
238
|
['a', 'a', 'b', 'c', 'c']
|
239
239
|
|. a . a . b . c . c .|
|
@@ -562,7 +562,8 @@ Syntax error at or near token 3>>>c<<<:
|
|
562
562
|
Expected one of: ['a', 'b'], found a 'c' instead.
|
563
563
|
MSG
|
564
564
|
err = StandardError
|
565
|
-
expect { subject.parse(wrong)}
|
565
|
+
expect { subject.parse(wrong) }
|
566
|
+
.to raise_error(err, err_msg.chomp)
|
566
567
|
=begin
|
567
568
|
expect(parse_result.success?).to eq(false)
|
568
569
|
|
@@ -17,20 +17,19 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
17
17
|
let(:output) { StringIO.new('', 'w') }
|
18
18
|
|
19
19
|
let(:token_seq) do
|
20
|
-
literals =
|
21
|
-
literals.map {|lexeme| Token.new(lexeme, nil)}
|
20
|
+
literals = %w(I saw John with a dog)
|
21
|
+
literals.map { |lexeme| Token.new(lexeme, nil) }
|
22
22
|
end
|
23
|
-
|
24
|
-
subject { ParseTracer.new(1, output, token_seq) }
|
23
|
+
|
24
|
+
subject { ParseTracer.new(1, output, token_seq) }
|
25
25
|
|
26
26
|
context 'Creation & initialization:' do
|
27
27
|
it 'should accept trace level 0' do
|
28
28
|
expect { ParseTracer.new(0, output, token_seq) }.not_to raise_error
|
29
29
|
expect(output.string).to eq('')
|
30
30
|
end
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
|
32
|
+
|
34
33
|
it 'should accept trace level 1' do
|
35
34
|
expect { ParseTracer.new(1, output, token_seq) }.not_to raise_error
|
36
35
|
expectations = <<-SNIPPET
|
@@ -39,7 +38,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
39
38
|
SNIPPET
|
40
39
|
expect(output.string).to eq(expectations)
|
41
40
|
end
|
42
|
-
|
41
|
+
|
43
42
|
it 'should accept trace level 2' do
|
44
43
|
expect { ParseTracer.new(2, output, token_seq) }.not_to raise_error
|
45
44
|
expectations = <<-SNIPPET
|
@@ -48,16 +47,16 @@ SNIPPET
|
|
48
47
|
SNIPPET
|
49
48
|
expect(output.string).to eq(expectations)
|
50
49
|
end
|
51
|
-
|
50
|
+
|
52
51
|
it 'should know the trace level' do
|
53
52
|
expect(subject.level).to eq(1)
|
54
53
|
end
|
55
|
-
|
54
|
+
|
56
55
|
it 'should know the output stream' do
|
57
56
|
expect(subject.ostream).to eq(output)
|
58
|
-
end
|
57
|
+
end
|
59
58
|
end # context
|
60
|
-
|
59
|
+
|
61
60
|
context 'Provided services:' do
|
62
61
|
let(:t_a) { Syntax::Terminal.new('A') }
|
63
62
|
let(:t_b) { Syntax::Terminal.new('B') }
|
@@ -72,7 +71,7 @@ SNIPPET
|
|
72
71
|
let(:dotted_rule) { DottedItem.new(sample_prod, 2) }
|
73
72
|
let(:complete_rule) { DottedItem.new(sample_prod, 3) }
|
74
73
|
let(:sample_parse_state) { ParseState.new(dotted_rule, origin_val) }
|
75
|
-
|
74
|
+
|
76
75
|
# Factory method.
|
77
76
|
def parse_state(origin, aDottedRule)
|
78
77
|
ParseState.new(aDottedRule, origin)
|
@@ -85,6 +84,7 @@ SNIPPET
|
|
85
84
|
expectations = <<-SNIPPET
|
86
85
|
|[------] . . . . .| [0:1] sentence => A B . C
|
87
86
|
SNIPPET
|
87
|
+
expect(output.string).to eq(expectations)
|
88
88
|
|
89
89
|
# Case: token in the middle
|
90
90
|
subject.ostream.string = ''
|
@@ -92,13 +92,15 @@ SNIPPET
|
|
92
92
|
expectations = <<-SNIPPET
|
93
93
|
|. . . [------] . .| [3:4] sentence => A B . C
|
94
94
|
SNIPPET
|
95
|
-
|
95
|
+
expect(output.string).to eq(expectations)
|
96
|
+
|
96
97
|
# Case: token at the end
|
97
98
|
subject.ostream.string = ''
|
98
99
|
subject.trace_scanning(6, parse_state(5, dotted_rule))
|
99
100
|
expectations = <<-SNIPPET
|
100
101
|
|. . . . . [------]| [5:6] sentence => A B . C
|
101
102
|
SNIPPET
|
103
|
+
expect(output.string).to eq(expectations)
|
102
104
|
end
|
103
105
|
|
104
106
|
|
@@ -109,8 +111,8 @@ SNIPPET
|
|
109
111
|
expectations = <<-SNIPPET
|
110
112
|
|> . . . . . .| [0:0] sentence => A B . C
|
111
113
|
SNIPPET
|
112
|
-
expect(output.string).to eq(expectations)
|
113
|
-
|
114
|
+
expect(output.string).to eq(expectations)
|
115
|
+
|
114
116
|
# Case: stateset in the middle
|
115
117
|
subject.ostream.string = ''
|
116
118
|
subject.trace_prediction(3, sample_parse_state)
|
@@ -118,7 +120,7 @@ SNIPPET
|
|
118
120
|
|. . . > . . .| [3:3] sentence => A B . C
|
119
121
|
SNIPPET
|
120
122
|
expect(output.string).to eq(expectations)
|
121
|
-
|
123
|
+
|
122
124
|
# Case: final stateset
|
123
125
|
subject.ostream.string = ''
|
124
126
|
subject.trace_prediction(6, parse_state(6, dotted_rule))
|
@@ -136,7 +138,7 @@ SNIPPET
|
|
136
138
|
|[=========================================]| [0:6] sentence => A B C .
|
137
139
|
SNIPPET
|
138
140
|
expect(output.string).to eq(expectations)
|
139
|
-
|
141
|
+
|
140
142
|
# Case: step at the start (complete)
|
141
143
|
subject.ostream.string = ''
|
142
144
|
subject.trace_completion(1, parse_state(0, complete_rule))
|
@@ -144,7 +146,7 @@ SNIPPET
|
|
144
146
|
|[------] . . . . .| [0:1] sentence => A B C .
|
145
147
|
SNIPPET
|
146
148
|
expect(output.string).to eq(expectations)
|
147
|
-
|
149
|
+
|
148
150
|
# Case: step at the start (not complete)
|
149
151
|
subject.ostream.string = ''
|
150
152
|
subject.trace_completion(1, parse_state(0, dotted_rule))
|
@@ -152,7 +154,7 @@ SNIPPET
|
|
152
154
|
|[------> . . . . .| [0:1] sentence => A B . C
|
153
155
|
SNIPPET
|
154
156
|
expect(output.string).to eq(expectations)
|
155
|
-
|
157
|
+
|
156
158
|
# Case: step at the middle (complete)
|
157
159
|
subject.ostream.string = ''
|
158
160
|
subject.trace_completion(4, parse_state(2, complete_rule))
|
@@ -160,7 +162,7 @@ SNIPPET
|
|
160
162
|
|. . [-------------] . .| [2:4] sentence => A B C .
|
161
163
|
SNIPPET
|
162
164
|
expect(output.string).to eq(expectations)
|
163
|
-
|
165
|
+
|
164
166
|
# Case: step at the middle (not complete)
|
165
167
|
subject.ostream.string = ''
|
166
168
|
subject.trace_completion(4, parse_state(2, dotted_rule))
|
@@ -168,7 +170,7 @@ SNIPPET
|
|
168
170
|
|. . [-------------> . .| [2:4] sentence => A B . C
|
169
171
|
SNIPPET
|
170
172
|
expect(output.string).to eq(expectations)
|
171
|
-
|
173
|
+
|
172
174
|
# Case: step at the end (complete)
|
173
175
|
subject.ostream.string = ''
|
174
176
|
subject.trace_completion(6, parse_state(3, complete_rule))
|
@@ -176,7 +178,7 @@ SNIPPET
|
|
176
178
|
|. . . [--------------------]| [3:6] sentence => A B C .
|
177
179
|
SNIPPET
|
178
180
|
expect(output.string).to eq(expectations)
|
179
|
-
|
181
|
+
|
180
182
|
# Case: step at the end (not complete)
|
181
183
|
subject.ostream.string = ''
|
182
184
|
subject.trace_completion(6, parse_state(3, dotted_rule))
|
@@ -190,4 +192,4 @@ SNIPPET
|
|
190
192
|
end # module
|
191
193
|
end # module
|
192
194
|
|
193
|
-
# End of file
|
195
|
+
# End of file
|
@@ -74,7 +74,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
74
74
|
|
75
75
|
it 'should emit trace level 1 info' do
|
76
76
|
tracer = ParseTracer.new(1, output, grm1_tokens)
|
77
|
-
|
77
|
+
Parsing.new(start_dotted_rule, grm1_tokens, tracer)
|
78
78
|
expectations = <<-SNIPPET
|
79
79
|
['a', 'a', 'b', 'c', 'c']
|
80
80
|
|. a . a . b . c . c .|
|
@@ -101,7 +101,8 @@ SNIPPET
|
|
101
101
|
it 'should complain when trying to push a nil dotted item' do
|
102
102
|
err = StandardError
|
103
103
|
msg = 'Dotted item may not be nil'
|
104
|
-
expect{ subject.push_state(nil, 1, 1, :prediction) }
|
104
|
+
expect { subject.push_state(nil, 1, 1, :prediction) }
|
105
|
+
.to raise_error(err, msg)
|
105
106
|
end
|
106
107
|
|
107
108
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rley
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dimitri Geshef
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-06-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|