treetop 1.5.3 → 1.6.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/Rakefile +9 -3
- data/doc/pitfalls_and_advanced_techniques.markdown +1 -1
- data/doc/sitegen.rb +1 -1
- data/doc/syntactic_recognition.markdown +2 -0
- data/doc/tt.1 +1 -1
- data/lib/treetop/compiler/metagrammar.rb +81 -13
- data/lib/treetop/compiler/metagrammar.treetop +67 -13
- data/lib/treetop/compiler/node_classes/anything_symbol.rb +5 -1
- data/lib/treetop/compiler/node_classes/character_class.rb +6 -2
- data/lib/treetop/compiler/node_classes/choice.rb +9 -5
- data/lib/treetop/compiler/node_classes/nonterminal.rb +2 -2
- data/lib/treetop/compiler/node_classes/parenthesized_expression.rb +5 -1
- data/lib/treetop/compiler/node_classes/parsing_expression.rb +12 -2
- data/lib/treetop/compiler/node_classes/predicate.rb +8 -1
- data/lib/treetop/compiler/node_classes/predicate_block.rb +7 -0
- data/lib/treetop/compiler/node_classes/repetition.rb +31 -11
- data/lib/treetop/compiler/node_classes/sequence.rb +5 -1
- data/lib/treetop/compiler/node_classes/terminal.rb +12 -2
- data/lib/treetop/runtime/compiled_parser.rb +12 -6
- data/lib/treetop/runtime/syntax_node.rb +24 -15
- data/lib/treetop/runtime/terminal_parse_failure.rb +4 -3
- data/lib/treetop/version.rb +2 -2
- data/spec/compiler/and_predicate_spec.rb +1 -1
- data/spec/compiler/anything_symbol_spec.rb +4 -1
- data/spec/compiler/character_class_spec.rb +4 -1
- data/spec/compiler/choice_spec.rb +20 -11
- data/spec/compiler/failure_propagation_functional_spec.rb +1 -1
- data/spec/compiler/grammar_spec.rb +4 -1
- data/spec/compiler/not_predicate_spec.rb +20 -6
- data/spec/compiler/occurrence_range_spec.rb +25 -28
- data/spec/compiler/one_or_more_spec.rb +2 -2
- data/spec/compiler/optional_spec.rb +2 -2
- data/spec/compiler/parenthesized_expression_spec.rb +15 -1
- data/spec/compiler/semantic_predicate_spec.rb +17 -16
- data/spec/compiler/sequence_spec.rb +1 -1
- data/spec/compiler/terminal_spec.rb +8 -1
- data/spec/compiler/terminal_symbol_spec.rb +4 -1
- data/spec/compiler/zero_or_more_spec.rb +4 -2
- data/spec/runtime/compiled_parser_spec.rb +33 -3
- metadata +20 -21
- data/examples/lambda_calculus/lambda_calculus +0 -0
data/lib/treetop/version.rb
CHANGED
@@ -21,7 +21,10 @@ module CharacterClassSpec
|
|
21
21
|
end
|
22
22
|
|
23
23
|
it "does not match single characters outside of that range" do
|
24
|
-
parse('8')
|
24
|
+
parse('8') do |result|
|
25
|
+
result.should be_nil
|
26
|
+
parser.terminal_failures.size.should == 1
|
27
|
+
end
|
25
28
|
parse('a').should be_nil
|
26
29
|
end
|
27
30
|
|
@@ -2,42 +2,51 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module ChoiceSpec
|
4
4
|
describe "A choice between terminal symbols" do
|
5
|
-
testing_expression '"foo" { def foo_method; end } / "bar" { def bar_method; end } / "baz" { def baz_method; end }'
|
5
|
+
testing_expression '("foo" { def foo_method; end } / "bar" { def bar_method; end } / "baz" { def baz_method; end }) {def bat_method; end}'
|
6
6
|
|
7
7
|
it "successfully parses input matching any of the alternatives, returning a node that responds to methods defined in its respective inline module" do
|
8
8
|
result = parse('foo')
|
9
9
|
result.should_not be_nil
|
10
10
|
result.should respond_to(:foo_method)
|
11
|
-
|
11
|
+
result.should_not respond_to(:bar_method)
|
12
|
+
result.should_not respond_to(:baz_method)
|
13
|
+
result.should respond_to(:bat_method)
|
14
|
+
|
12
15
|
result = parse('bar')
|
13
16
|
result.should_not be_nil
|
17
|
+
result.should_not respond_to(:foo_method)
|
14
18
|
result.should respond_to(:bar_method)
|
15
|
-
|
19
|
+
result.should_not respond_to(:baz_method)
|
20
|
+
result.should respond_to(:bat_method)
|
21
|
+
|
16
22
|
result = parse('baz')
|
17
23
|
result.should_not be_nil
|
24
|
+
result.should_not respond_to(:foo_method)
|
25
|
+
result.should_not respond_to(:bar_method)
|
18
26
|
result.should respond_to(:baz_method)
|
27
|
+
result.should respond_to(:bat_method)
|
19
28
|
end
|
20
|
-
|
29
|
+
|
21
30
|
it "upon parsing a string matching the second alternative, records the failure of the first terminal" do
|
22
31
|
result = parse('bar')
|
23
32
|
terminal_failures = parser.terminal_failures
|
24
33
|
terminal_failures.size.should == 1
|
25
34
|
failure = terminal_failures[0]
|
26
|
-
failure.expected_string.should == 'foo'
|
35
|
+
failure.expected_string.should == '"foo"'
|
27
36
|
failure.index.should == 0
|
28
37
|
end
|
29
|
-
|
38
|
+
|
30
39
|
it "upon parsing a string matching the third alternative, records the failure of the first two terminals" do
|
31
40
|
result = parse('baz')
|
32
|
-
|
41
|
+
|
33
42
|
terminal_failures = parser.terminal_failures
|
34
|
-
|
43
|
+
|
35
44
|
terminal_failures.size.should == 2
|
36
45
|
|
37
46
|
failure_1 = terminal_failures[0]
|
38
47
|
failure_1.expected_string == 'foo'
|
39
48
|
failure_1.index.should == 0
|
40
|
-
|
49
|
+
|
41
50
|
failure_2 = terminal_failures[1]
|
42
51
|
failure_2.expected_string == 'bar'
|
43
52
|
failure_2.index.should == 0
|
@@ -53,7 +62,7 @@ module ChoiceSpec
|
|
53
62
|
end
|
54
63
|
end
|
55
64
|
|
56
|
-
describe "A choice between terminals followed by a block" do
|
65
|
+
describe "A choice between terminals followed by a block" do
|
57
66
|
testing_expression "('a'/ 'bb' / [c]) { def a_method; end }"
|
58
67
|
|
59
68
|
it "extends a match of any of its subexpressions with a module created from the block" do
|
@@ -68,7 +77,7 @@ module ChoiceSpec
|
|
68
77
|
end
|
69
78
|
end
|
70
79
|
|
71
|
-
describe "a choice followed by a declared module" do
|
80
|
+
describe "a choice followed by a declared module" do
|
72
81
|
testing_expression "('a'/ 'bb' / [c]) <ChoiceSpec::TestModule>"
|
73
82
|
|
74
83
|
it "extends a match of any of its subexpressions with a module created from the block" do
|
@@ -15,7 +15,7 @@ describe "An expression for braces surrounding zero or more letters followed by
|
|
15
15
|
terminal_failures.size.should == 1
|
16
16
|
failure = terminal_failures[0]
|
17
17
|
failure.index.should == 6
|
18
|
-
failure.expected_string.should == ';'
|
18
|
+
failure.expected_string.should == "';'"
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
@@ -31,7 +31,10 @@ module GrammarSpec
|
|
31
31
|
end
|
32
32
|
|
33
33
|
it "fails if it does not parse all input" do
|
34
|
-
parse('barbarbazbaz')
|
34
|
+
parse('barbarbazbaz') do |result|
|
35
|
+
result.should be_nil
|
36
|
+
parser.terminal_failures.size.should == 1
|
37
|
+
end
|
35
38
|
end
|
36
39
|
|
37
40
|
it "mixes in included modules" do
|
@@ -5,7 +5,21 @@ module NotPredicateSpec
|
|
5
5
|
testing_expression '!"foo"'
|
6
6
|
|
7
7
|
it "fails to parse input matching the terminal symbol" do
|
8
|
-
parse('foo')
|
8
|
+
parse('foo') do |result|
|
9
|
+
result.should be_nil
|
10
|
+
parser.terminal_failures.size.should == 1
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "A !-predicated character class symbol" do
|
16
|
+
testing_expression '![aeiou]'
|
17
|
+
|
18
|
+
it "fails to parse input matching the terminal symbol" do
|
19
|
+
parse('e') do |result|
|
20
|
+
result.should be_nil
|
21
|
+
parser.terminal_failures.size.should == 1
|
22
|
+
end
|
9
23
|
end
|
10
24
|
end
|
11
25
|
|
@@ -20,10 +34,7 @@ module NotPredicateSpec
|
|
20
34
|
parse('foo') do |result|
|
21
35
|
result.should_not be_nil
|
22
36
|
terminal_failures = parser.terminal_failures
|
23
|
-
terminal_failures.size.should ==
|
24
|
-
failure = terminal_failures.first
|
25
|
-
failure.index.should == 3
|
26
|
-
failure.expected_string.should == 'bar'
|
37
|
+
terminal_failures.size.should == 0
|
27
38
|
end
|
28
39
|
end
|
29
40
|
end
|
@@ -32,7 +43,10 @@ module NotPredicateSpec
|
|
32
43
|
testing_expression '!("a" "b" "cc")'
|
33
44
|
|
34
45
|
it "fails to parse matching input" do
|
35
|
-
parse('abcc')
|
46
|
+
parse('abcc') do |result|
|
47
|
+
result.should be_nil
|
48
|
+
parser.terminal_failures.size.should == 1
|
49
|
+
end
|
36
50
|
end
|
37
51
|
end
|
38
52
|
end
|
@@ -14,10 +14,7 @@ module OccurrenceRangeSpec
|
|
14
14
|
result.should respond_to(:a_method)
|
15
15
|
|
16
16
|
terminal_failures = parser.terminal_failures
|
17
|
-
terminal_failures.size.should ==
|
18
|
-
failure = terminal_failures.first
|
19
|
-
failure.index.should == 0
|
20
|
-
failure.expected_string.should == 'foo'
|
17
|
+
terminal_failures.size.should == 0
|
21
18
|
end
|
22
19
|
end
|
23
20
|
|
@@ -28,10 +25,7 @@ module OccurrenceRangeSpec
|
|
28
25
|
result.should respond_to(:a_method)
|
29
26
|
|
30
27
|
terminal_failures = parser.terminal_failures
|
31
|
-
terminal_failures.size.should ==
|
32
|
-
failure = terminal_failures.first
|
33
|
-
failure.index.should == 0
|
34
|
-
failure.expected_string.should == 'foo'
|
28
|
+
terminal_failures.size.should == 0
|
35
29
|
end
|
36
30
|
end
|
37
31
|
|
@@ -42,10 +36,7 @@ module OccurrenceRangeSpec
|
|
42
36
|
result.should respond_to(:a_method)
|
43
37
|
|
44
38
|
terminal_failures = parser.terminal_failures
|
45
|
-
terminal_failures.size.should ==
|
46
|
-
failure = terminal_failures.first
|
47
|
-
failure.index.should == 3
|
48
|
-
failure.expected_string.should == 'foo'
|
39
|
+
terminal_failures.size.should == 0
|
49
40
|
end
|
50
41
|
end
|
51
42
|
|
@@ -60,14 +51,23 @@ module OccurrenceRangeSpec
|
|
60
51
|
end
|
61
52
|
end
|
62
53
|
|
63
|
-
it "fails to parses
|
54
|
+
it "fails to parses two of that terminal but fails because of an extra one" do
|
64
55
|
parse("foofoofoo") do |result|
|
65
56
|
result.should be_nil
|
66
57
|
|
67
|
-
|
68
|
-
terminal_failures.size.should == 0
|
58
|
+
parser.terminal_failures.size.should == 1
|
69
59
|
end
|
70
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
71
|
end
|
72
72
|
|
73
73
|
describe "two to four of a terminal symbol followed by a node class declaration and a block" do
|
@@ -80,7 +80,7 @@ module OccurrenceRangeSpec
|
|
80
80
|
terminal_failures.size.should == 1
|
81
81
|
failure = terminal_failures.first
|
82
82
|
failure.index.should == 0
|
83
|
-
failure.expected_string.should == 'foo'
|
83
|
+
failure.expected_string.should == '"foo"'
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
@@ -92,7 +92,7 @@ module OccurrenceRangeSpec
|
|
92
92
|
terminal_failures.size.should == 1
|
93
93
|
failure = terminal_failures.first
|
94
94
|
failure.index.should == 3
|
95
|
-
failure.expected_string.should == 'foo'
|
95
|
+
failure.expected_string.should == '"foo"'
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
@@ -103,10 +103,7 @@ module OccurrenceRangeSpec
|
|
103
103
|
result.should respond_to(:a_method)
|
104
104
|
|
105
105
|
terminal_failures = parser.terminal_failures
|
106
|
-
terminal_failures.size.should ==
|
107
|
-
failure = terminal_failures.first
|
108
|
-
failure.index.should == 6
|
109
|
-
failure.expected_string.should == 'foo'
|
106
|
+
terminal_failures.size.should == 0
|
110
107
|
end
|
111
108
|
end
|
112
109
|
|
@@ -117,16 +114,16 @@ module OccurrenceRangeSpec
|
|
117
114
|
result.should respond_to(:a_method)
|
118
115
|
|
119
116
|
terminal_failures = parser.terminal_failures
|
120
|
-
|
117
|
+
terminal_failures.size.should == 0
|
121
118
|
end
|
122
119
|
end
|
123
120
|
|
124
|
-
it "fails to parses
|
121
|
+
it "fails to parses four of that terminal because there's an extra unconsumed one" do
|
125
122
|
parse("foofoofoofoofoo") do |result|
|
126
123
|
result.should be_nil
|
127
124
|
|
128
125
|
terminal_failures = parser.terminal_failures
|
129
|
-
|
126
|
+
terminal_failures.size.should == 1
|
130
127
|
end
|
131
128
|
end
|
132
129
|
end
|
@@ -141,7 +138,7 @@ module OccurrenceRangeSpec
|
|
141
138
|
terminal_failures.size.should == 1
|
142
139
|
failure = terminal_failures.first
|
143
140
|
failure.index.should == 0
|
144
|
-
failure.expected_string.should == 'foo'
|
141
|
+
failure.expected_string.should == '"foo"'
|
145
142
|
end
|
146
143
|
end
|
147
144
|
|
@@ -153,7 +150,7 @@ module OccurrenceRangeSpec
|
|
153
150
|
terminal_failures.size.should == 1
|
154
151
|
failure = terminal_failures.first
|
155
152
|
failure.index.should == 3
|
156
|
-
failure.expected_string.should == 'foo'
|
153
|
+
failure.expected_string.should == '"foo"'
|
157
154
|
end
|
158
155
|
end
|
159
156
|
|
@@ -167,7 +164,7 @@ module OccurrenceRangeSpec
|
|
167
164
|
terminal_failures.size.should == 1
|
168
165
|
failure = terminal_failures.first
|
169
166
|
failure.index.should == 6
|
170
|
-
failure.expected_string.should == 'foo'
|
167
|
+
failure.expected_string.should == '"foo"'
|
171
168
|
end
|
172
169
|
end
|
173
170
|
|
@@ -181,7 +178,7 @@ module OccurrenceRangeSpec
|
|
181
178
|
terminal_failures.size.should == 1
|
182
179
|
failure = terminal_failures.first
|
183
180
|
failure.index.should == 12
|
184
|
-
failure.expected_string.should == 'foo'
|
181
|
+
failure.expected_string.should == '"foo"'
|
185
182
|
end
|
186
183
|
end
|
187
184
|
end
|
@@ -14,7 +14,7 @@ module OneOrMoreSpec
|
|
14
14
|
terminal_failures.size.should == 1
|
15
15
|
failure = terminal_failures.first
|
16
16
|
failure.index.should == 0
|
17
|
-
failure.expected_string.should == 'foo'
|
17
|
+
failure.expected_string.should == '"foo"'
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
@@ -28,7 +28,7 @@ module OneOrMoreSpec
|
|
28
28
|
terminal_failures.size.should == 1
|
29
29
|
failure = terminal_failures.first
|
30
30
|
failure.index.should == 6
|
31
|
-
failure.expected_string.should == 'foo'
|
31
|
+
failure.expected_string.should == '"foo"'
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
@@ -17,7 +17,7 @@ module OptionalSpec
|
|
17
17
|
terminal_failures.size.should == 1
|
18
18
|
failure = terminal_failures.first
|
19
19
|
failure.index.should == 0
|
20
|
-
failure.expected_string.should == 'foo'
|
20
|
+
failure.expected_string.should == '"foo"'
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
@@ -30,7 +30,7 @@ module OptionalSpec
|
|
30
30
|
terminal_failures.size.should == 1
|
31
31
|
failure = terminal_failures.first
|
32
32
|
failure.index.should == 0
|
33
|
-
failure.expected_string.should == 'foo'
|
33
|
+
failure.expected_string.should == '"foo"'
|
34
34
|
end
|
35
35
|
end
|
36
36
|
end
|
@@ -13,7 +13,21 @@ module ParenthesizedExpressionSpec
|
|
13
13
|
testing_expression '(!"foo")'
|
14
14
|
|
15
15
|
it "should behave as normal" do
|
16
|
-
parse('foo')
|
16
|
+
parse('foo') do |result|
|
17
|
+
result.should be_nil
|
18
|
+
parser.terminal_failures.size.should == 1
|
19
|
+
end
|
17
20
|
end
|
18
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
|
+
result.should respond_to(:inner)
|
28
|
+
result.should respond_to(:outer)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
19
33
|
end
|
@@ -17,7 +17,7 @@ module SemanticPredicateSpec
|
|
17
17
|
parse('foo', :consume_all_input => false) do |result|
|
18
18
|
result.should be_nil
|
19
19
|
terminal_failures = parser.terminal_failures
|
20
|
-
|
20
|
+
terminal_failures.size.should == 1
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
@@ -44,7 +44,7 @@ module SemanticPredicateSpec
|
|
44
44
|
result.should be_nil
|
45
45
|
$value.should == 'prior '
|
46
46
|
terminal_failures = parser.terminal_failures
|
47
|
-
|
47
|
+
terminal_failures.size.should == 1
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
@@ -63,13 +63,13 @@ module SemanticPredicateSpec
|
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
66
|
-
it "fails with
|
66
|
+
it "fails with one terminal_failure if the block returns false" do
|
67
67
|
$ok_to_succeed = false
|
68
68
|
parse('prior foo', :consume_all_input => false) do |result|
|
69
69
|
result.should be_nil
|
70
70
|
$value.should == 'prior '
|
71
71
|
terminal_failures = parser.terminal_failures
|
72
|
-
|
72
|
+
terminal_failures.size.should == 1
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
@@ -78,10 +78,12 @@ module SemanticPredicateSpec
|
|
78
78
|
parse('foo', :consume_all_input => false) do |result|
|
79
79
|
result.should be_nil
|
80
80
|
terminal_failures = parser.terminal_failures
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
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>'
|
85
87
|
end
|
86
88
|
end
|
87
89
|
|
@@ -103,7 +105,7 @@ module SemanticPredicateSpec
|
|
103
105
|
parse('foo', :consume_all_input => false) do |result|
|
104
106
|
result.should be_nil
|
105
107
|
terminal_failures = parser.terminal_failures
|
106
|
-
|
108
|
+
terminal_failures.size.should == 1
|
107
109
|
end
|
108
110
|
end
|
109
111
|
|
@@ -130,7 +132,7 @@ module SemanticPredicateSpec
|
|
130
132
|
result.should be_nil
|
131
133
|
$value.should == 'prior '
|
132
134
|
terminal_failures = parser.terminal_failures
|
133
|
-
|
135
|
+
terminal_failures.size.should == 1
|
134
136
|
end
|
135
137
|
end
|
136
138
|
|
@@ -149,13 +151,13 @@ module SemanticPredicateSpec
|
|
149
151
|
end
|
150
152
|
end
|
151
153
|
|
152
|
-
it "fails with
|
154
|
+
it "fails with one terminal_failure if the block returns true" do
|
153
155
|
$ok_to_succeed = true
|
154
156
|
parse('prior foo', :consume_all_input => false) do |result|
|
155
157
|
result.should be_nil
|
156
158
|
$value.should == 'prior '
|
157
159
|
terminal_failures = parser.terminal_failures
|
158
|
-
|
160
|
+
terminal_failures.size.should == 1
|
159
161
|
end
|
160
162
|
end
|
161
163
|
|
@@ -164,10 +166,9 @@ module SemanticPredicateSpec
|
|
164
166
|
parse('foo', :consume_all_input => false) do |result|
|
165
167
|
result.should be_nil
|
166
168
|
terminal_failures = parser.terminal_failures
|
167
|
-
terminal_failures.size.should ==
|
168
|
-
|
169
|
-
|
170
|
-
failure.expected_string.should == 'prior '
|
169
|
+
terminal_failures.size.should == 2
|
170
|
+
terminal_failures[0].index.should == 0
|
171
|
+
terminal_failures[0].expected_string.should == '"prior "'
|
171
172
|
end
|
172
173
|
end
|
173
174
|
|