rattler 0.2.2 → 0.3.0
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.
- data/README.rdoc +83 -64
- data/features/grammar/comments.feature +24 -0
- data/features/grammar/list_matching.feature +41 -0
- data/features/grammar/symantic_action.feature +30 -12
- data/lib/rattler/back_end/parser_generator/assert_generator.rb +27 -27
- data/lib/rattler/back_end/parser_generator/choice_generator.rb +29 -29
- data/lib/rattler/back_end/parser_generator/direct_action_generator.rb +17 -17
- data/lib/rattler/back_end/parser_generator/disallow_generator.rb +27 -27
- data/lib/rattler/back_end/parser_generator/dispatch_action_generator.rb +17 -17
- data/lib/rattler/back_end/parser_generator/expr_generator.rb +129 -40
- data/lib/rattler/back_end/parser_generator/label_generator.rb +15 -15
- data/lib/rattler/back_end/parser_generator/list1_generator.rb +61 -0
- data/lib/rattler/back_end/parser_generator/list_generating.rb +71 -0
- data/lib/rattler/back_end/parser_generator/list_generator.rb +57 -0
- data/lib/rattler/back_end/parser_generator/one_or_more_generator.rb +14 -15
- data/lib/rattler/back_end/parser_generator/optional_generator.rb +24 -24
- data/lib/rattler/back_end/parser_generator/predicate_propogating.rb +9 -9
- data/lib/rattler/back_end/parser_generator/repeat_generating.rb +16 -16
- data/lib/rattler/back_end/parser_generator/sequence_generator.rb +40 -40
- data/lib/rattler/back_end/parser_generator/skip_generator.rb +18 -18
- data/lib/rattler/back_end/parser_generator/skip_propogating.rb +5 -5
- data/lib/rattler/back_end/parser_generator/sub_generating.rb +128 -0
- data/lib/rattler/back_end/parser_generator/token_generator.rb +15 -15
- data/lib/rattler/back_end/parser_generator/token_propogating.rb +1 -1
- data/lib/rattler/back_end/parser_generator/zero_or_more_generator.rb +12 -13
- data/lib/rattler/back_end/parser_generator.rb +10 -7
- data/lib/rattler/grammar/grammar_parser.rb +16 -21
- data/lib/rattler/grammar/metagrammar.rb +1039 -1035
- data/lib/rattler/grammar/rattler.rtlr +28 -28
- data/lib/rattler/parsers/action_code.rb +20 -9
- data/lib/rattler/parsers/fail.rb +7 -1
- data/lib/rattler/parsers/list.rb +57 -0
- data/lib/rattler/parsers/list1.rb +58 -0
- data/lib/rattler/parsers/parser_dsl.rb +60 -38
- data/lib/rattler/parsers.rb +5 -3
- data/lib/rattler/runtime/extended_packrat_parser.rb +88 -20
- data/lib/rattler/runtime/packrat_parser.rb +21 -14
- data/lib/rattler/runtime/parser.rb +74 -18
- data/lib/rattler/runtime/recursive_descent_parser.rb +15 -46
- data/spec/rattler/back_end/compiler_spec.rb +173 -107
- data/spec/rattler/back_end/parser_generator/list1_generator_spec.rb +304 -0
- data/spec/rattler/back_end/parser_generator/list_generator_spec.rb +288 -0
- data/spec/rattler/grammar/grammar_parser_spec.rb +65 -76
- data/spec/rattler/parsers/action_code_spec.rb +84 -34
- data/spec/rattler/parsers/direct_action_spec.rb +56 -34
- data/spec/rattler/parsers/fail_spec.rb +20 -0
- data/spec/rattler/parsers/list1_spec.rb +82 -0
- data/spec/rattler/parsers/list_spec.rb +82 -0
- data/spec/rattler/parsers/parser_dsl_spec.rb +48 -19
- data/spec/rattler/runtime/extended_packrat_parser_spec.rb +0 -1
- metadata +92 -173
- data/bin/rtlr.bat +0 -3
- data/lib/rattler/back_end/parser_generator/generator_helper.rb +0 -130
- data/lib/rattler/back_end/parser_generator/generators.rb +0 -86
- data/lib/rattler/back_end/parser_generator/nested_generators.rb +0 -15
- data/lib/rattler/back_end/parser_generator/top_level_generators.rb +0 -15
@@ -2,26 +2,35 @@ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
|
2
2
|
|
3
3
|
describe DirectAction do
|
4
4
|
include CombinatorParserSpecHelper
|
5
|
-
|
5
|
+
|
6
6
|
describe '#parse' do
|
7
|
-
|
7
|
+
|
8
8
|
context 'with a capturing parser' do
|
9
|
-
|
10
|
-
subject { DirectAction[Match[/[[:digit:]]+/], '|
|
11
|
-
|
9
|
+
|
10
|
+
subject { DirectAction[Match[/[[:digit:]]+/], '|s| s * 2'] }
|
11
|
+
|
12
12
|
context 'when the parser matches' do
|
13
13
|
it 'applies the action binding the captured results as arguments' do
|
14
14
|
parsing('451a').should result_in('451451').at(3)
|
15
15
|
end
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
context 'when the parser fails' do
|
19
19
|
it 'fails' do
|
20
20
|
parsing('foo').should fail
|
21
21
|
end
|
22
22
|
end
|
23
|
+
|
24
|
+
context 'using the "_" character' do
|
25
|
+
|
26
|
+
subject { DirectAction[Match[/[[:digit:]]+/], '_ * 2'] }
|
27
|
+
|
28
|
+
it 'applies the action binding the captured result as "_"' do
|
29
|
+
parsing('451a').should result_in('451451').at(3)
|
30
|
+
end
|
31
|
+
end
|
23
32
|
end
|
24
|
-
|
33
|
+
|
25
34
|
context 'with a sequence parser' do
|
26
35
|
subject do
|
27
36
|
DirectAction[
|
@@ -29,86 +38,99 @@ describe DirectAction do
|
|
29
38
|
'|l, r| "#{r} -> #{l}"'
|
30
39
|
]
|
31
40
|
end
|
32
|
-
|
41
|
+
|
33
42
|
context 'when the parser matches' do
|
34
43
|
it 'applies the action binding the captured results as arguments' do
|
35
44
|
parsing('val=42 ').should result_in('42 -> val').at(6)
|
36
45
|
end
|
37
46
|
end
|
47
|
+
|
48
|
+
context 'using the "_" character' do
|
49
|
+
subject do
|
50
|
+
DirectAction[
|
51
|
+
Sequence[Match[/[[:alpha:]]+/], Skip[Match[/\=/]], Match[/[[:digit:]]+/]],
|
52
|
+
'_.join " <- "'
|
53
|
+
]
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'applies the action binding the captured result array as "_"' do
|
57
|
+
parsing('val=42 ').should result_in('val <- 42').at(6)
|
58
|
+
end
|
59
|
+
end
|
38
60
|
end
|
39
|
-
|
61
|
+
|
40
62
|
context 'with an optional parser' do
|
41
|
-
|
42
|
-
subject { DirectAction[Optional[Match[/\d+/]], '|
|
43
|
-
|
63
|
+
|
64
|
+
subject { DirectAction[Optional[Match[/\d+/]], '|s| s'] }
|
65
|
+
|
44
66
|
context 'when the nested parser matches' do
|
45
67
|
it 'applies the action to an array containing the match' do
|
46
68
|
parsing('451a').should result_in(['451']).at(3)
|
47
69
|
end
|
48
70
|
end
|
49
|
-
|
71
|
+
|
50
72
|
context 'when the nested parser fails' do
|
51
73
|
it 'applies the action to an empty array' do
|
52
74
|
parsing('foo').should result_in([]).at(0)
|
53
75
|
end
|
54
76
|
end
|
55
77
|
end
|
56
|
-
|
78
|
+
|
57
79
|
context 'with a zero-or-more parser' do
|
58
|
-
|
59
|
-
subject { DirectAction[ZeroOrMore[Match[/\d/]], '|
|
60
|
-
|
80
|
+
|
81
|
+
subject { DirectAction[ZeroOrMore[Match[/\d/]], '|s| s'] }
|
82
|
+
|
61
83
|
context 'when the nested parser matches' do
|
62
84
|
it 'applies the action to an array containing the matches' do
|
63
85
|
parsing('451a').should result_in(['4', '5', '1']).at(3)
|
64
86
|
end
|
65
87
|
end
|
66
|
-
|
88
|
+
|
67
89
|
context 'when the nested parser fails' do
|
68
90
|
it 'applies the action to an empty array' do
|
69
91
|
parsing('foo').should result_in([]).at(0)
|
70
92
|
end
|
71
93
|
end
|
72
94
|
end
|
73
|
-
|
95
|
+
|
74
96
|
context 'with a one-or-more parser' do
|
75
|
-
|
76
|
-
subject { DirectAction[OneOrMore[Match[/\d/]], '|
|
77
|
-
|
97
|
+
|
98
|
+
subject { DirectAction[OneOrMore[Match[/\d/]], '|s| s'] }
|
99
|
+
|
78
100
|
context 'when the nested parser matches' do
|
79
101
|
it 'applies the action to an array containing the matches' do
|
80
102
|
parsing('451a').should result_in(['4', '5', '1']).at(3)
|
81
103
|
end
|
82
104
|
end
|
83
|
-
|
105
|
+
|
84
106
|
context 'when the nested parser fails' do
|
85
107
|
it 'fails' do
|
86
108
|
parsing('foo').should fail
|
87
109
|
end
|
88
110
|
end
|
89
111
|
end
|
90
|
-
|
112
|
+
|
91
113
|
context 'with a token parser' do
|
92
|
-
subject { DirectAction[Token[Match[/[[:digit:]]+/]], '|
|
93
|
-
|
114
|
+
subject { DirectAction[Token[Match[/[[:digit:]]+/]], '|s| s.to_i'] }
|
115
|
+
|
94
116
|
context 'when the parser matches' do
|
95
117
|
it 'applies the action to the matched string' do
|
96
118
|
parsing('42 ').should result_in(42).at(2)
|
97
119
|
end
|
98
120
|
end
|
99
121
|
end
|
100
|
-
|
122
|
+
|
101
123
|
context 'with a non-capturing parser' do
|
102
|
-
|
124
|
+
|
103
125
|
subject { DirectAction[Skip[Match[/\w+/]], '42'] }
|
104
|
-
|
126
|
+
|
105
127
|
context 'when the parser matches' do
|
106
128
|
it 'applies the action with no arguments' do
|
107
129
|
parsing('abc123 ').should result_in(42).at(6)
|
108
130
|
end
|
109
131
|
end
|
110
132
|
end
|
111
|
-
|
133
|
+
|
112
134
|
context 'with a sequence of labeled parsers' do
|
113
135
|
subject do
|
114
136
|
DirectAction[
|
@@ -127,16 +149,16 @@ describe DirectAction do
|
|
127
149
|
end
|
128
150
|
end
|
129
151
|
end
|
130
|
-
|
152
|
+
|
131
153
|
describe '#capturing?' do
|
132
|
-
|
154
|
+
|
133
155
|
context 'with a capturing parser' do
|
134
156
|
subject { DirectAction[Match[/\w+/], ''] }
|
135
157
|
it 'is true' do
|
136
158
|
subject.should be_capturing
|
137
159
|
end
|
138
160
|
end
|
139
|
-
|
161
|
+
|
140
162
|
context 'with a non-capturing parser' do
|
141
163
|
subject { DirectAction[Skip[Match[/\s*/]], ''] }
|
142
164
|
it 'is false' do
|
@@ -144,5 +166,5 @@ describe DirectAction do
|
|
144
166
|
end
|
145
167
|
end
|
146
168
|
end
|
147
|
-
|
169
|
+
|
148
170
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe Assert do
|
4
|
+
include CombinatorParserSpecHelper
|
5
|
+
|
6
|
+
subject { Fail[:expr, 'malformed expression'] }
|
7
|
+
|
8
|
+
describe '#parse' do
|
9
|
+
it 'fails' do
|
10
|
+
parsing('anything').should fail
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#capturing?' do
|
15
|
+
it 'is false' do
|
16
|
+
subject.should_not be_capturing
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe List1 do
|
4
|
+
include CombinatorParserSpecHelper
|
5
|
+
|
6
|
+
describe '#parse' do
|
7
|
+
|
8
|
+
context 'with a capturing term parser' do
|
9
|
+
|
10
|
+
subject { List1[Match[/\w+/], Match[/[,;]/]] }
|
11
|
+
|
12
|
+
context 'when no terms match' do
|
13
|
+
it 'fails' do
|
14
|
+
parsing(' ').should fail
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'when a single term matches' do
|
19
|
+
it 'returns an array with the result of matching the term' do
|
20
|
+
parsing('foo').should result_in(['foo']).at(3)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'when multiple terms match' do
|
25
|
+
it 'returns an array with the results of matching the terms' do
|
26
|
+
parsing('foo,bar;baz ').should result_in(['foo', 'bar', 'baz']).at(11)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'with a separator not followed by a term' do
|
31
|
+
it 'matches without consuming the extra separator' do
|
32
|
+
parsing('foo,bar,').should result_in(['foo', 'bar']).at(7)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'with a non-capturing parser' do
|
38
|
+
|
39
|
+
subject { List1[Skip[Match[/\w+/]], Match[/[,;]/]] }
|
40
|
+
|
41
|
+
context 'when no terms match' do
|
42
|
+
it 'fails' do
|
43
|
+
parsing(' ').should fail
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'when a single term matches' do
|
48
|
+
it 'returns true consuming the term' do
|
49
|
+
parsing('foo ').should result_in(true).at(3)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'when multiple terms match' do
|
54
|
+
it 'returns true consuming the list' do
|
55
|
+
parsing('foo,bar;baz ').should result_in(true).at(11)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#capturing?' do
|
62
|
+
|
63
|
+
context 'with a capturing term parser' do
|
64
|
+
|
65
|
+
subject { List1[Match[/\w+/], Match[/[,;]/]] }
|
66
|
+
|
67
|
+
it 'is true' do
|
68
|
+
subject.should be_capturing
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'with a non-capturing term parser' do
|
73
|
+
|
74
|
+
subject { List1[Skip[Match[/\w+/]], Match[/[,;]/]] }
|
75
|
+
|
76
|
+
it 'is true' do
|
77
|
+
subject.should_not be_capturing
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe List do
|
4
|
+
include CombinatorParserSpecHelper
|
5
|
+
|
6
|
+
describe '#parse' do
|
7
|
+
|
8
|
+
context 'with a capturing term parser' do
|
9
|
+
|
10
|
+
subject { List[Match[/\w+/], Match[/[,;]/]] }
|
11
|
+
|
12
|
+
context 'when no terms match' do
|
13
|
+
it 'returns an empty array without advancing' do
|
14
|
+
parsing(' ').should result_in([]).at(0)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'when a single term matches' do
|
19
|
+
it 'returns an array with the result of matching the term' do
|
20
|
+
parsing('foo').should result_in(['foo']).at(3)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'when multiple terms match' do
|
25
|
+
it 'returns an array with the results of matching the terms' do
|
26
|
+
parsing('foo,bar;baz ').should result_in(['foo', 'bar', 'baz']).at(11)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'with a separator not followed by a term' do
|
31
|
+
it 'matches without consuming the extra separator' do
|
32
|
+
parsing('foo,bar,').should result_in(['foo', 'bar']).at(7)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'with a non-capturing parser' do
|
38
|
+
|
39
|
+
subject { List[Skip[Match[/\w+/]], Match[/[,;]/]] }
|
40
|
+
|
41
|
+
context 'when no terms match' do
|
42
|
+
it 'returns true without advancing' do
|
43
|
+
parsing(' ').should result_in(true).at(0)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'when a single term matches' do
|
48
|
+
it 'returns true consuming the term' do
|
49
|
+
parsing('foo ').should result_in(true).at(3)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'when multiple terms match' do
|
54
|
+
it 'returns true consuming the list' do
|
55
|
+
parsing('foo,bar;baz ').should result_in(true).at(11)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#capturing?' do
|
62
|
+
|
63
|
+
context 'with a capturing term parser' do
|
64
|
+
|
65
|
+
subject { List[Match[/\w+/], Match[/[,;]/]] }
|
66
|
+
|
67
|
+
it 'is true' do
|
68
|
+
subject.should be_capturing
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'with a non-capturing term parser' do
|
73
|
+
|
74
|
+
subject { List[Skip[Match[/\w+/]], Match[/[,;]/]] }
|
75
|
+
|
76
|
+
it 'is true' do
|
77
|
+
subject.should_not be_capturing
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
@@ -3,9 +3,9 @@ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
|
3
3
|
include Rattler::Parsers
|
4
4
|
|
5
5
|
describe ParserDSL do
|
6
|
-
|
6
|
+
|
7
7
|
subject { ParserDSL.new }
|
8
|
-
|
8
|
+
|
9
9
|
describe '#match' do
|
10
10
|
context 'given a regexp' do
|
11
11
|
it 'creates a regexp match parser' do
|
@@ -34,7 +34,7 @@ describe ParserDSL do
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
describe '#optional' do
|
39
39
|
context 'given a parser' do
|
40
40
|
it 'creates an optional parser' do
|
@@ -47,7 +47,7 @@ describe ParserDSL do
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
describe '#zero_or_more' do
|
52
52
|
context 'given a parser' do
|
53
53
|
it 'creates a zero-or-more parser' do
|
@@ -60,7 +60,7 @@ describe ParserDSL do
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
describe '#one_or_more' do
|
65
65
|
context 'given a parser' do
|
66
66
|
it 'creates a one-or-more parser' do
|
@@ -73,7 +73,36 @@ describe ParserDSL do
|
|
73
73
|
end
|
74
74
|
end
|
75
75
|
end
|
76
|
-
|
76
|
+
|
77
|
+
describe '#list' do
|
78
|
+
context 'given parsers' do
|
79
|
+
it 'creates a list parser' do
|
80
|
+
subject.list(subject.match(/\w+/), subject.match(/,/)).
|
81
|
+
should == List[Match[/\w+/], Match[/,/]]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
context 'given match arguments' do
|
85
|
+
it 'creates a list parser' do
|
86
|
+
subject.list(/\w+/, ',').should == List[Match[/\w+/], Match[/,/]]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe '#list1' do
|
92
|
+
context 'given parsers' do
|
93
|
+
it 'creates a list parser' do
|
94
|
+
subject.list1(subject.match(/\w+/), subject.match(/,/)).
|
95
|
+
should == List1[Match[/\w+/], Match[/,/]]
|
96
|
+
end
|
97
|
+
end
|
98
|
+
context 'given match arguments' do
|
99
|
+
it 'creates a list parser' do
|
100
|
+
subject.list1(/\w+/, ',').
|
101
|
+
should == List1[Match[/\w+/], Match[/,/]]
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
77
106
|
describe '#assert' do
|
78
107
|
context 'given a parser' do
|
79
108
|
it 'create an assert parser' do
|
@@ -86,7 +115,7 @@ describe ParserDSL do
|
|
86
115
|
end
|
87
116
|
end
|
88
117
|
end
|
89
|
-
|
118
|
+
|
90
119
|
describe '#disallow' do
|
91
120
|
context 'given a parser' do
|
92
121
|
it 'creates a disallow parser' do
|
@@ -99,13 +128,13 @@ describe ParserDSL do
|
|
99
128
|
end
|
100
129
|
end
|
101
130
|
end
|
102
|
-
|
131
|
+
|
103
132
|
describe '#eof' do
|
104
133
|
it 'creates the eof parser' do
|
105
134
|
subject.eof.should == Eof[]
|
106
135
|
end
|
107
136
|
end
|
108
|
-
|
137
|
+
|
109
138
|
describe '#dispatch_action' do
|
110
139
|
context 'given a parser' do
|
111
140
|
context 'given options' do
|
@@ -134,7 +163,7 @@ describe ParserDSL do
|
|
134
163
|
end
|
135
164
|
end
|
136
165
|
end
|
137
|
-
|
166
|
+
|
138
167
|
describe '#direct_action' do
|
139
168
|
context 'given a parser' do
|
140
169
|
it 'creates a direct-action parser' do
|
@@ -149,7 +178,7 @@ describe ParserDSL do
|
|
149
178
|
end
|
150
179
|
end
|
151
180
|
end
|
152
|
-
|
181
|
+
|
153
182
|
describe '#token' do
|
154
183
|
context 'given a parser' do
|
155
184
|
it 'creates a token parser' do
|
@@ -168,7 +197,7 @@ describe ParserDSL do
|
|
168
197
|
end
|
169
198
|
end
|
170
199
|
end
|
171
|
-
|
200
|
+
|
172
201
|
describe '#skip' do
|
173
202
|
context 'given a parser' do
|
174
203
|
it 'creates a skip parser' do
|
@@ -181,7 +210,7 @@ describe ParserDSL do
|
|
181
210
|
end
|
182
211
|
end
|
183
212
|
end
|
184
|
-
|
213
|
+
|
185
214
|
describe '#label' do
|
186
215
|
context 'given a parser' do
|
187
216
|
it 'creates a label parser' do
|
@@ -194,25 +223,25 @@ describe ParserDSL do
|
|
194
223
|
end
|
195
224
|
end
|
196
225
|
end
|
197
|
-
|
226
|
+
|
198
227
|
describe '#fail' do
|
199
228
|
it 'creates a fail-expr parser' do
|
200
229
|
subject.fail('var expected').should == Fail[:expr, 'var expected']
|
201
230
|
end
|
202
231
|
end
|
203
|
-
|
232
|
+
|
204
233
|
describe '#fail_rule' do
|
205
234
|
it 'creates a fail-rule parser' do
|
206
235
|
subject.fail_rule('var expected').should == Fail[:rule, 'var expected']
|
207
236
|
end
|
208
237
|
end
|
209
|
-
|
238
|
+
|
210
239
|
describe '#fail_parse' do
|
211
240
|
it 'creates a fail-parse parser' do
|
212
241
|
subject.fail_parse('var expected').should == Fail[:parse, 'var expected']
|
213
242
|
end
|
214
243
|
end
|
215
|
-
|
244
|
+
|
216
245
|
describe '#rule' do
|
217
246
|
context 'given a block' do
|
218
247
|
it 'creates a rule' do
|
@@ -227,7 +256,7 @@ describe ParserDSL do
|
|
227
256
|
end
|
228
257
|
end
|
229
258
|
end
|
230
|
-
|
259
|
+
|
231
260
|
describe '#rules' do
|
232
261
|
context 'given a block' do
|
233
262
|
it 'creates multiple rules' do
|
@@ -242,5 +271,5 @@ describe ParserDSL do
|
|
242
271
|
end
|
243
272
|
end
|
244
273
|
end
|
245
|
-
|
274
|
+
|
246
275
|
end
|