treetop 1.6.8 → 1.6.9
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/Gemfile +18 -0
- data/History.txt +18 -0
- data/Rakefile +3 -28
- data/Treetop.tmbundle/Preferences/Comments.tmPreferences +28 -0
- data/Treetop.tmbundle/Snippets/grammar ___ end.tmSnippet +20 -0
- data/Treetop.tmbundle/Snippets/rule ___ end.tmSnippet +18 -0
- data/Treetop.tmbundle/Support/nibs/SyntaxTreeViewer.nib/designable.nib +1524 -0
- data/Treetop.tmbundle/Support/nibs/SyntaxTreeViewer.nib/keyedobjects.nib +0 -0
- data/Treetop.tmbundle/Support/syntax_tree_viewer.rb +117 -0
- data/Treetop.tmbundle/Syntaxes/Treetop Grammar.tmLanguage +358 -0
- data/Treetop.tmbundle/info.plist +10 -0
- data/lib/treetop/runtime/compiled_parser.rb +15 -2
- data/lib/treetop/version.rb +1 -1
- data/treetop.gemspec +25 -157
- metadata +12 -56
- data/spec/compiler/and_predicate_spec.rb +0 -36
- data/spec/compiler/anything_symbol_spec.rb +0 -47
- data/spec/compiler/character_class_spec.rb +0 -304
- data/spec/compiler/choice_spec.rb +0 -89
- data/spec/compiler/circular_compilation_spec.rb +0 -30
- data/spec/compiler/failure_propagation_functional_spec.rb +0 -21
- data/spec/compiler/grammar_compiler_spec.rb +0 -113
- data/spec/compiler/grammar_spec.rb +0 -44
- data/spec/compiler/multibyte_chars_spec.rb +0 -38
- data/spec/compiler/namespace_spec.rb +0 -42
- data/spec/compiler/nonterminal_symbol_spec.rb +0 -40
- data/spec/compiler/not_predicate_spec.rb +0 -52
- data/spec/compiler/occurrence_range_spec.rb +0 -186
- data/spec/compiler/one_or_more_spec.rb +0 -35
- data/spec/compiler/optional_spec.rb +0 -37
- data/spec/compiler/parenthesized_expression_spec.rb +0 -34
- data/spec/compiler/parsing_rule_spec.rb +0 -61
- data/spec/compiler/repeated_subrule_spec.rb +0 -29
- data/spec/compiler/semantic_predicate_spec.rb +0 -176
- data/spec/compiler/sequence_spec.rb +0 -129
- data/spec/compiler/terminal_spec.rb +0 -177
- data/spec/compiler/terminal_symbol_spec.rb +0 -40
- data/spec/compiler/test_grammar.treetop +0 -7
- data/spec/compiler/test_grammar.tt +0 -7
- data/spec/compiler/test_grammar_do.treetop +0 -7
- data/spec/compiler/test_grammar_magic_coding.treetop +0 -8
- data/spec/compiler/test_grammar_magic_encoding.treetop +0 -8
- data/spec/compiler/tt_compiler_spec.rb +0 -224
- data/spec/compiler/zero_or_more_spec.rb +0 -58
- data/spec/composition/a.treetop +0 -11
- data/spec/composition/b.treetop +0 -11
- data/spec/composition/c.treetop +0 -10
- data/spec/composition/d.treetop +0 -10
- data/spec/composition/f.treetop +0 -17
- data/spec/composition/grammar_composition_spec.rb +0 -40
- data/spec/composition/subfolder/e_includes_c.treetop +0 -15
- data/spec/ruby_extensions/string_spec.rb +0 -32
- data/spec/runtime/compiled_parser_spec.rb +0 -153
- data/spec/runtime/syntax_node_spec.rb +0 -77
- data/spec/spec_helper.rb +0 -123
@@ -1,186 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module OccurrenceRangeSpec
|
4
|
-
class Foo < Treetop::Runtime::SyntaxNode
|
5
|
-
end
|
6
|
-
|
7
|
-
describe "zero to two of a terminal symbol followed by a node class declaration and a block" do
|
8
|
-
testing_expression '"foo"..2 <OccurrenceRangeSpec::Foo> { def a_method; end }'
|
9
|
-
|
10
|
-
it "successfully parses epsilon, reporting a failure" do
|
11
|
-
parse('') do |result|
|
12
|
-
result.should_not be_nil
|
13
|
-
result.should be_an_instance_of(Foo)
|
14
|
-
result.should respond_to(:a_method)
|
15
|
-
|
16
|
-
terminal_failures = parser.terminal_failures
|
17
|
-
terminal_failures.size.should == 0
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
it "successfully parses epsilon, returning an instance declared node class and recording a terminal failure" do
|
22
|
-
parse('') do |result|
|
23
|
-
result.should_not be_nil
|
24
|
-
result.should be_an_instance_of(Foo)
|
25
|
-
result.should respond_to(:a_method)
|
26
|
-
|
27
|
-
terminal_failures = parser.terminal_failures
|
28
|
-
terminal_failures.size.should == 0
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
it "successfully parses one of that terminal, returning an instance of the declared node class and recording a terminal failure" do
|
33
|
-
parse("foo") do |result|
|
34
|
-
result.should_not be_nil
|
35
|
-
result.should be_an_instance_of(Foo)
|
36
|
-
result.should respond_to(:a_method)
|
37
|
-
|
38
|
-
terminal_failures = parser.terminal_failures
|
39
|
-
terminal_failures.size.should == 0
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
it "successfully parses two of that terminal, returning an instance of the declared node class and reporting no failure" do
|
44
|
-
parse("foofoo") do |result|
|
45
|
-
result.should_not be_nil
|
46
|
-
result.should be_an_instance_of(Foo)
|
47
|
-
result.should respond_to(:a_method)
|
48
|
-
|
49
|
-
terminal_failures = parser.terminal_failures
|
50
|
-
terminal_failures.size.should == 0
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
it "fails to parses two of that terminal but fails because of an extra one" do
|
55
|
-
parse("foofoofoo") do |result|
|
56
|
-
result.should be_nil
|
57
|
-
|
58
|
-
parser.terminal_failures.size.should == 1
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
it "parses two of three of that terminal, reporting no failure" do
|
63
|
-
parse("foofoofoo", :consume_all_input => false) do |result|
|
64
|
-
result.should_not be_nil
|
65
|
-
result.elements.size.should == 2
|
66
|
-
|
67
|
-
parser.terminal_failures.size.should == 0
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
end
|
72
|
-
|
73
|
-
describe "two to four of a terminal symbol followed by a node class declaration and a block" do
|
74
|
-
testing_expression '"foo" 2..4 <OccurrenceRangeSpec::Foo> { def a_method; end }'
|
75
|
-
|
76
|
-
it "fails to parse epsilon, reporting a failure" do
|
77
|
-
parse('') do |result|
|
78
|
-
result.should be_nil
|
79
|
-
terminal_failures = parser.terminal_failures
|
80
|
-
terminal_failures.size.should == 1
|
81
|
-
failure = terminal_failures.first
|
82
|
-
failure.index.should == 0
|
83
|
-
failure.expected_string.should == '"foo"'
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
it "fails to parse one of that terminal, returning an instance of the declared node class and recording a terminal failure" do
|
88
|
-
parse("foo") do |result|
|
89
|
-
result.should be_nil
|
90
|
-
|
91
|
-
terminal_failures = parser.terminal_failures
|
92
|
-
terminal_failures.size.should == 1
|
93
|
-
failure = terminal_failures.first
|
94
|
-
failure.index.should == 3
|
95
|
-
failure.expected_string.should == '"foo"'
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
it "successfully parses two of that terminal, returning an instance of the declared node class and reporting no failure" do
|
100
|
-
parse("foofoo") do |result|
|
101
|
-
result.should_not be_nil
|
102
|
-
result.should be_an_instance_of(Foo)
|
103
|
-
result.should respond_to(:a_method)
|
104
|
-
|
105
|
-
terminal_failures = parser.terminal_failures
|
106
|
-
terminal_failures.size.should == 0
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
it "successfully parses four of that terminal, returning an instance of the declared node class and reporting no failure" do
|
111
|
-
parse("foofoofoofoo") do |result|
|
112
|
-
result.should_not be_nil
|
113
|
-
result.should be_an_instance_of(Foo)
|
114
|
-
result.should respond_to(:a_method)
|
115
|
-
|
116
|
-
terminal_failures = parser.terminal_failures
|
117
|
-
terminal_failures.size.should == 0
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
it "fails to parses four of that terminal because there's an extra unconsumed one" do
|
122
|
-
parse("foofoofoofoofoo") do |result|
|
123
|
-
result.should be_nil
|
124
|
-
|
125
|
-
terminal_failures = parser.terminal_failures
|
126
|
-
terminal_failures.size.should == 1
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
describe "two to any number of a terminal symbol followed by a node class declaration and a block" do
|
132
|
-
testing_expression '"foo" 2.. <OccurrenceRangeSpec::Foo> { def a_method; end }'
|
133
|
-
|
134
|
-
it "fails to parse epsilon, reporting a failure" do
|
135
|
-
parse('') do |result|
|
136
|
-
result.should be_nil
|
137
|
-
terminal_failures = parser.terminal_failures
|
138
|
-
terminal_failures.size.should == 1
|
139
|
-
failure = terminal_failures.first
|
140
|
-
failure.index.should == 0
|
141
|
-
failure.expected_string.should == '"foo"'
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
it "fails to parse one of that terminal, returning an instance of the declared node class and recording a terminal failure" do
|
146
|
-
parse("foo") do |result|
|
147
|
-
result.should be_nil
|
148
|
-
|
149
|
-
terminal_failures = parser.terminal_failures
|
150
|
-
terminal_failures.size.should == 1
|
151
|
-
failure = terminal_failures.first
|
152
|
-
failure.index.should == 3
|
153
|
-
failure.expected_string.should == '"foo"'
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
it "successfully parses two of that terminal, returning an instance of the declared node class and reporting no failure" do
|
158
|
-
parse("foofoo") do |result|
|
159
|
-
result.should_not be_nil
|
160
|
-
result.should be_an_instance_of(Foo)
|
161
|
-
result.should respond_to(:a_method)
|
162
|
-
|
163
|
-
terminal_failures = parser.terminal_failures
|
164
|
-
terminal_failures.size.should == 1
|
165
|
-
failure = terminal_failures.first
|
166
|
-
failure.index.should == 6
|
167
|
-
failure.expected_string.should == '"foo"'
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
it "successfully parses four of that terminal, returning an instance of the declared node class and reporting a failure on the fifth" do
|
172
|
-
parse("foofoofoofoo") do |result|
|
173
|
-
result.should_not be_nil
|
174
|
-
result.should be_an_instance_of(Foo)
|
175
|
-
result.should respond_to(:a_method)
|
176
|
-
|
177
|
-
terminal_failures = parser.terminal_failures
|
178
|
-
terminal_failures.size.should == 1
|
179
|
-
failure = terminal_failures.first
|
180
|
-
failure.index.should == 12
|
181
|
-
failure.expected_string.should == '"foo"'
|
182
|
-
end
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module OneOrMoreSpec
|
4
|
-
class Foo < Treetop::Runtime::SyntaxNode
|
5
|
-
end
|
6
|
-
|
7
|
-
describe "one or more of a terminal symbol followed by a node class declaration and a block" do
|
8
|
-
testing_expression '"foo"+ <OneOrMoreSpec::Foo> { def a_method; end }'
|
9
|
-
|
10
|
-
it "fails to parse epsilon, reporting a failure" do
|
11
|
-
parse('') do |result|
|
12
|
-
result.should be_nil
|
13
|
-
terminal_failures = parser.terminal_failures
|
14
|
-
terminal_failures.size.should == 1
|
15
|
-
failure = terminal_failures.first
|
16
|
-
failure.index.should == 0
|
17
|
-
failure.expected_string.should == '"foo"'
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
it "successfully parses two of that terminal in a row, returning an instance of the declared node class and reporting the failure the third parsing attempt" do
|
22
|
-
parse("foofoo") do |result|
|
23
|
-
result.should_not be_nil
|
24
|
-
result.should be_an_instance_of(Foo)
|
25
|
-
result.should respond_to(:a_method)
|
26
|
-
|
27
|
-
terminal_failures = parser.terminal_failures
|
28
|
-
terminal_failures.size.should == 1
|
29
|
-
failure = terminal_failures.first
|
30
|
-
failure.index.should == 6
|
31
|
-
failure.expected_string.should == '"foo"'
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module OptionalSpec
|
4
|
-
describe "An optional terminal symbol" do
|
5
|
-
testing_expression '"foo"?'
|
6
|
-
|
7
|
-
it "parses input matching the terminal" do
|
8
|
-
parse('foo').should_not be_nil
|
9
|
-
end
|
10
|
-
|
11
|
-
it "parses epsilon, recording a failure" do
|
12
|
-
parse('') do |result|
|
13
|
-
result.should_not be_nil
|
14
|
-
result.interval.should == (0...0)
|
15
|
-
|
16
|
-
terminal_failures = parser.terminal_failures
|
17
|
-
terminal_failures.size.should == 1
|
18
|
-
failure = terminal_failures.first
|
19
|
-
failure.index.should == 0
|
20
|
-
failure.expected_string.should == '"foo"'
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
it "parses input not matching the terminal, returning an epsilon result and recording a failure" do
|
25
|
-
parse('bar', :consume_all_input => false) do |result|
|
26
|
-
result.should_not be_nil
|
27
|
-
result.interval.should == (0...0)
|
28
|
-
|
29
|
-
terminal_failures = parser.terminal_failures
|
30
|
-
terminal_failures.size.should == 1
|
31
|
-
failure = terminal_failures.first
|
32
|
-
failure.index.should == 0
|
33
|
-
failure.expected_string.should == '"foo"'
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module ParenthesizedExpressionSpec
|
4
|
-
describe "An unadorned expression inside of parentheses" do
|
5
|
-
testing_expression '("foo")'
|
6
|
-
|
7
|
-
it "should behave as normal" do
|
8
|
-
parse('foo').should_not be_nil
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
describe "A prefixed-expression inside of parentheses" do
|
13
|
-
testing_expression '(!"foo")'
|
14
|
-
|
15
|
-
it "should behave as normal" do
|
16
|
-
parse('foo') do |result|
|
17
|
-
result.should be_nil
|
18
|
-
parser.terminal_failures.size.should == 1
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
describe "An expression with code both inside and outside parentheses" do
|
24
|
-
testing_expression '("foo" { def inner; end } ) { def outer; end} '
|
25
|
-
it "should extend both code modules " do
|
26
|
-
parse('foo') do |result|
|
27
|
-
skip "Arbitrarily nested modules are not yet compiled"
|
28
|
-
result.should respond_to(:inner)
|
29
|
-
result.should respond_to(:outer)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
@@ -1,61 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module ParsingRuleSpec
|
4
|
-
describe "a grammar with one parsing rule" do
|
5
|
-
|
6
|
-
testing_grammar %{
|
7
|
-
grammar Foo
|
8
|
-
rule bar
|
9
|
-
"baz"
|
10
|
-
end
|
11
|
-
end
|
12
|
-
}
|
13
|
-
|
14
|
-
it "stores and retrieves nodes in its node cache" do
|
15
|
-
parser = self.class.const_get(:FooParser).new
|
16
|
-
parser.send(:prepare_to_parse, 'baz')
|
17
|
-
node_cache = parser.send(:node_cache)
|
18
|
-
|
19
|
-
node_cache[:bar][0].should be_nil
|
20
|
-
|
21
|
-
parser._nt_bar
|
22
|
-
|
23
|
-
cached_node = node_cache[:bar][0]
|
24
|
-
cached_node.should be_an_instance_of(Runtime::SyntaxNode)
|
25
|
-
cached_node.text_value.should == 'baz'
|
26
|
-
|
27
|
-
parser.instance_eval { @index = 0 }
|
28
|
-
parser._nt_bar.should equal(cached_node)
|
29
|
-
parser.index.should == cached_node.interval.end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
|
34
|
-
describe "a grammar with choice that uses the cache and has a subsequent expression" do
|
35
|
-
testing_grammar %{
|
36
|
-
grammar Logic
|
37
|
-
rule expression
|
38
|
-
value_plus
|
39
|
-
/
|
40
|
-
value
|
41
|
-
end
|
42
|
-
|
43
|
-
rule value_plus
|
44
|
-
value "something else"
|
45
|
-
end
|
46
|
-
|
47
|
-
rule value
|
48
|
-
[a-z]
|
49
|
-
/
|
50
|
-
"foobar" # the subsequent expression that needs cached.interval.end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
}
|
54
|
-
|
55
|
-
it "parses a single-character value and generates a node from the cache" do
|
56
|
-
result = parse('a')
|
57
|
-
result.should be_a(Treetop::Runtime::SyntaxNode)
|
58
|
-
result.elements.should be_nil
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module RepeatedSubruleSpec
|
4
|
-
describe "a repeated subrule" do
|
5
|
-
testing_grammar %{
|
6
|
-
grammar Foo
|
7
|
-
rule foo
|
8
|
-
a:'a' space b:'b' space 'cc'
|
9
|
-
end
|
10
|
-
|
11
|
-
rule space
|
12
|
-
' '
|
13
|
-
end
|
14
|
-
end
|
15
|
-
}
|
16
|
-
|
17
|
-
it "should produce a parser having sequence-numbered node accessor methods" do
|
18
|
-
parse("a b cc") do |result|
|
19
|
-
result.should_not be_nil
|
20
|
-
result.should respond_to(:space1)
|
21
|
-
result.should respond_to(:space2)
|
22
|
-
result.should_not respond_to(:space)
|
23
|
-
result.should respond_to(:a)
|
24
|
-
result.should respond_to(:b)
|
25
|
-
result.should_not respond_to(:c)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,176 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module SemanticPredicateSpec
|
4
|
-
describe "An &-predicate block" do
|
5
|
-
testing_expression '& {|| $ok_to_succeed}'
|
6
|
-
|
7
|
-
it "succeeds if it returns true, returning an epsilon syntax node" do
|
8
|
-
$ok_to_succeed = true
|
9
|
-
parse('foo', :consume_all_input => false) do |result|
|
10
|
-
result.should_not be_nil
|
11
|
-
result.interval.should == (0...0)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
it "fails if it returns false" do
|
16
|
-
$ok_to_succeed = false
|
17
|
-
parse('foo', :consume_all_input => false) do |result|
|
18
|
-
result.should be_nil
|
19
|
-
terminal_failures = parser.terminal_failures
|
20
|
-
terminal_failures.size.should == 1
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
describe "A sequence of a terminal and an &-predicate block" do
|
27
|
-
testing_expression '"prior " &{|s| $value = s[0].text_value; $ok_to_succeed }'
|
28
|
-
|
29
|
-
it "matches the input terminal and consumes it if the block returns true, seeing the terminal in the sequence" do
|
30
|
-
$ok_to_succeed = true
|
31
|
-
$value = nil
|
32
|
-
parse('prior foo', :consume_all_input => false) do |result|
|
33
|
-
result.should_not be_nil
|
34
|
-
result.elements[0].text_value.should == "prior "
|
35
|
-
result.text_value.should == 'prior '
|
36
|
-
$value.should == 'prior '
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
it "fails if the block returns false, but sees the terminal in the sequence" do
|
41
|
-
$ok_to_succeed = false
|
42
|
-
$value = nil
|
43
|
-
parse('prior foo', :consume_all_input => false) do |result|
|
44
|
-
result.should be_nil
|
45
|
-
$value.should == 'prior '
|
46
|
-
terminal_failures = parser.terminal_failures
|
47
|
-
terminal_failures.size.should == 1
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
end
|
52
|
-
|
53
|
-
describe "A sequence of an optional terminal and an &-predicate block" do
|
54
|
-
testing_expression '"prior "? &{|s| $value = s[0].text_value; $ok_to_succeed}'
|
55
|
-
|
56
|
-
it "matches the input terminal and consumes it if the block returns true" do
|
57
|
-
$ok_to_succeed = true
|
58
|
-
parse('prior foo', :consume_all_input => false) do |result|
|
59
|
-
result.should_not be_nil
|
60
|
-
result.elements[0].text_value.should == "prior "
|
61
|
-
result.text_value.should == 'prior '
|
62
|
-
$value.should == 'prior '
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
it "fails with one terminal_failure if the block returns false" do
|
67
|
-
$ok_to_succeed = false
|
68
|
-
parse('prior foo', :consume_all_input => false) do |result|
|
69
|
-
result.should be_nil
|
70
|
-
$value.should == 'prior '
|
71
|
-
terminal_failures = parser.terminal_failures
|
72
|
-
terminal_failures.size.should == 1
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
it "fail and return the expected optional preceeding terminal as expected input if the block returns false" do
|
77
|
-
$ok_to_succeed = false
|
78
|
-
parse('foo', :consume_all_input => false) do |result|
|
79
|
-
result.should be_nil
|
80
|
-
terminal_failures = parser.terminal_failures
|
81
|
-
# We should get "prior " failed, and also the predicate block
|
82
|
-
terminal_failures.size.should == 2
|
83
|
-
terminal_failures[0].index.should == 0
|
84
|
-
terminal_failures[0].expected_string.should == '"prior "'
|
85
|
-
terminal_failures[1].index.should == 0
|
86
|
-
terminal_failures[1].expected_string.should == '<semantic predicate>'
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
end
|
91
|
-
|
92
|
-
describe "A !-predicate block" do
|
93
|
-
testing_expression '! {|| $ok_to_succeed}'
|
94
|
-
|
95
|
-
it "succeeds if it returns false, returning an epsilon syntax node" do
|
96
|
-
$ok_to_succeed = false
|
97
|
-
parse('foo', :consume_all_input => false) do |result|
|
98
|
-
result.should_not be_nil
|
99
|
-
result.interval.should == (0...0)
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
it "fails if it returns true" do
|
104
|
-
$ok_to_succeed = true
|
105
|
-
parse('foo', :consume_all_input => false) do |result|
|
106
|
-
result.should be_nil
|
107
|
-
terminal_failures = parser.terminal_failures
|
108
|
-
terminal_failures.size.should == 1
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
end
|
113
|
-
|
114
|
-
describe "A sequence of a terminal and an !-predicate block" do
|
115
|
-
testing_expression '"prior " !{|s| $value = s[0].text_value; $ok_to_succeed }'
|
116
|
-
|
117
|
-
it "matches the input terminal and consumes it if the block returns false, seeing the terminal in the sequence" do
|
118
|
-
$ok_to_succeed = false
|
119
|
-
$value = nil
|
120
|
-
parse('prior foo', :consume_all_input => false) do |result|
|
121
|
-
result.should_not be_nil
|
122
|
-
result.elements[0].text_value.should == "prior "
|
123
|
-
result.text_value.should == 'prior '
|
124
|
-
$value.should == 'prior '
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
it "fails if the block returns true, but sees the terminal in the sequence" do
|
129
|
-
$ok_to_succeed = true
|
130
|
-
$value = nil
|
131
|
-
parse('prior foo', :consume_all_input => false) do |result|
|
132
|
-
result.should be_nil
|
133
|
-
$value.should == 'prior '
|
134
|
-
terminal_failures = parser.terminal_failures
|
135
|
-
terminal_failures.size.should == 1
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
end
|
140
|
-
|
141
|
-
describe "A sequence of an optional terminal and an !-predicate block" do
|
142
|
-
testing_expression '"prior "? !{|s| $value = s[0].text_value; $ok_to_succeed}'
|
143
|
-
|
144
|
-
it "matches the input terminal and consumes it if the block returns false" do
|
145
|
-
$ok_to_succeed = false
|
146
|
-
parse('prior foo', :consume_all_input => false) do |result|
|
147
|
-
result.should_not be_nil
|
148
|
-
result.elements[0].text_value.should == "prior "
|
149
|
-
result.text_value.should == 'prior '
|
150
|
-
$value.should == 'prior '
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
it "fails with one terminal_failure if the block returns true" do
|
155
|
-
$ok_to_succeed = true
|
156
|
-
parse('prior foo', :consume_all_input => false) do |result|
|
157
|
-
result.should be_nil
|
158
|
-
$value.should == 'prior '
|
159
|
-
terminal_failures = parser.terminal_failures
|
160
|
-
terminal_failures.size.should == 1
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
it "fail and return the expected optional preceeding terminal as expected input if the block returns true" do
|
165
|
-
$ok_to_succeed = true
|
166
|
-
parse('foo', :consume_all_input => false) do |result|
|
167
|
-
result.should be_nil
|
168
|
-
terminal_failures = parser.terminal_failures
|
169
|
-
terminal_failures.size.should == 2
|
170
|
-
terminal_failures[0].index.should == 0
|
171
|
-
terminal_failures[0].expected_string.should == '"prior "'
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
end
|
176
|
-
end
|