OLD | NEW |
| (Empty) |
1 part of petitparser; | |
2 | |
3 /// A parser that delegates to another one. Normally users do not need to | |
4 /// directly use a delegate parser. | |
5 class DelegateParser extends Parser { | |
6 Parser _delegate; | |
7 | |
8 DelegateParser(this._delegate); | |
9 | |
10 @override | |
11 Result parseOn(Context context) { | |
12 return _delegate.parseOn(context); | |
13 } | |
14 | |
15 @override | |
16 List<Parser> get children => [_delegate]; | |
17 | |
18 @override | |
19 void replace(Parser source, Parser target) { | |
20 super.replace(source, target); | |
21 if (_delegate == source) { | |
22 _delegate = target; | |
23 } | |
24 } | |
25 | |
26 @override | |
27 Parser copy() => new DelegateParser(_delegate); | |
28 } | |
29 | |
30 /// A parser that succeeds only at the end of the input. | |
31 class EndOfInputParser extends DelegateParser { | |
32 final String _message; | |
33 | |
34 EndOfInputParser(parser, this._message) : super(parser); | |
35 | |
36 @override | |
37 Result parseOn(Context context) { | |
38 var result = _delegate.parseOn(context); | |
39 if (result.isFailure || result.position == result.buffer.length) { | |
40 return result; | |
41 } | |
42 return result.failure(_message, result.position); | |
43 } | |
44 | |
45 @override | |
46 String toString() => '${super.toString()}[$_message]'; | |
47 | |
48 @override | |
49 Parser copy() => new EndOfInputParser(_delegate, _message); | |
50 | |
51 @override | |
52 bool hasEqualProperties(Parser other) { | |
53 return other is EndOfInputParser && super.hasEqualProperties(other) | |
54 && _message == other._message; | |
55 } | |
56 } | |
57 | |
58 /// The and-predicate, a parser that succeeds whenever its delegate does, but | |
59 /// does not consume the input stream [Parr 1994, 1995]. | |
60 class AndParser extends DelegateParser { | |
61 AndParser(parser) : super(parser); | |
62 | |
63 @override | |
64 Result parseOn(Context context) { | |
65 var result = _delegate.parseOn(context); | |
66 if (result.isSuccess) { | |
67 return context.success(result.value); | |
68 } else { | |
69 return result; | |
70 } | |
71 } | |
72 | |
73 @override | |
74 Parser copy() => new AndParser(_delegate); | |
75 } | |
76 | |
77 /// The not-predicate, a parser that succeeds whenever its delegate does not, | |
78 /// but consumes no input [Parr 1994, 1995]. | |
79 class NotParser extends DelegateParser { | |
80 final String _message; | |
81 | |
82 NotParser(parser, this._message) : super(parser); | |
83 | |
84 @override | |
85 Result parseOn(Context context) { | |
86 var result = _delegate.parseOn(context); | |
87 if (result.isFailure) { | |
88 return context.success(null); | |
89 } else { | |
90 return context.failure(_message); | |
91 } | |
92 } | |
93 | |
94 @override | |
95 String toString() => '${super.toString()}[$_message]'; | |
96 | |
97 @override | |
98 Parser copy() => new NotParser(_delegate, _message); | |
99 | |
100 @override | |
101 bool hasEqualProperties(Parser other) { | |
102 return other is NotParser | |
103 && super.hasEqualProperties(other) | |
104 && _message == other._message; | |
105 } | |
106 } | |
107 | |
108 /// A parser that optionally parsers its delegate, or answers nil. | |
109 class OptionalParser extends DelegateParser { | |
110 final _otherwise; | |
111 | |
112 OptionalParser(parser, this._otherwise) : super(parser); | |
113 | |
114 @override | |
115 Result parseOn(Context context) { | |
116 var result = _delegate.parseOn(context); | |
117 if (result.isSuccess) { | |
118 return result; | |
119 } else { | |
120 return context.success(_otherwise); | |
121 } | |
122 } | |
123 | |
124 @override | |
125 Parser copy() => new OptionalParser(_delegate, _otherwise); | |
126 | |
127 @override | |
128 bool hasEqualProperties(Parser other) { | |
129 return other is OptionalParser | |
130 && super.hasEqualProperties(other) | |
131 && _otherwise == other._otherwise; | |
132 } | |
133 } | |
134 | |
135 /// Abstract parser that parses a list of things in some way. | |
136 abstract class ListParser extends Parser { | |
137 final List<Parser> _parsers; | |
138 | |
139 ListParser(this._parsers); | |
140 | |
141 @override | |
142 List<Parser> get children => _parsers; | |
143 | |
144 @override | |
145 void replace(Parser source, Parser target) { | |
146 super.replace(source, target); | |
147 for (var i = 0; i < _parsers.length; i++) { | |
148 if (_parsers[i] == source) { | |
149 _parsers[i] = target; | |
150 } | |
151 } | |
152 } | |
153 } | |
154 | |
155 /// A parser that uses the first parser that succeeds. | |
156 class ChoiceParser extends ListParser { | |
157 factory ChoiceParser(Iterable<Parser> parsers) { | |
158 return new ChoiceParser._(new List.from(parsers, growable: false)); | |
159 } | |
160 | |
161 ChoiceParser._(parsers) : super(parsers); | |
162 | |
163 @override | |
164 Result parseOn(Context context) { | |
165 var result; | |
166 for (var i = 0; i < _parsers.length; i++) { | |
167 result = _parsers[i].parseOn(context); | |
168 if (result.isSuccess) { | |
169 return result; | |
170 } | |
171 } | |
172 return result; | |
173 } | |
174 | |
175 @override | |
176 Parser or(Parser other) { | |
177 return new ChoiceParser(new List() | |
178 ..addAll(_parsers) | |
179 ..add(other)); | |
180 } | |
181 | |
182 @override | |
183 Parser copy() => new ChoiceParser(_parsers); | |
184 } | |
185 | |
186 /// A parser that parses a sequence of parsers. | |
187 class SequenceParser extends ListParser { | |
188 factory SequenceParser(Iterable<Parser> parsers) { | |
189 return new SequenceParser._(new List.from(parsers, growable: false)); | |
190 } | |
191 | |
192 SequenceParser._(parsers) : super(parsers); | |
193 | |
194 @override | |
195 Result parseOn(Context context) { | |
196 var current = context; | |
197 var elements = new List(_parsers.length); | |
198 for (var i = 0; i < _parsers.length; i++) { | |
199 var result = _parsers[i].parseOn(current); | |
200 if (result.isFailure) { | |
201 return result; | |
202 } | |
203 elements[i] = result.value; | |
204 current = result; | |
205 } | |
206 return current.success(elements); | |
207 } | |
208 | |
209 @override | |
210 Parser seq(Parser other) { | |
211 return new SequenceParser(new List() | |
212 ..addAll(_parsers) | |
213 ..add(other)); | |
214 } | |
215 | |
216 @override | |
217 Parser copy() => new SequenceParser(_parsers); | |
218 } | |
OLD | NEW |