Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(101)

Side by Side Diff: petitparser/lib/src/core/repeaters.dart

Issue 1400473008: Roll Observatory packages and add a roll script (Closed) Base URL: git@github.com:dart-lang/observatory_pub_packages.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « petitparser/lib/src/core/predicates.dart ('k') | petitparser/lib/src/core/token.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 part of petitparser;
2
3 /**
4 * An [int] used to mark an unbounded maximum repetition.
5 */
6 const int unbounded = -1;
7
8 /**
9 * An abstract parser that repeatedly parses between 'min' and 'max' instances o f
10 * its delegate.
11 */
12 abstract class RepeatingParser extends DelegateParser {
13 final int _min;
14 final int _max;
15
16 RepeatingParser(Parser parser, this._min, this._max) : super(parser) {
17 assert(0 <= _min);
18 assert(_max == unbounded || _min <= _max);
19 }
20
21 @override
22 String toString() {
23 var max = _max == unbounded ? '*' : _max;
24 return '${super.toString()}[$_min..$max]';
25 }
26
27 @override
28 bool hasEqualProperties(Parser other) {
29 return other is RepeatingParser
30 && super.hasEqualProperties(other)
31 && _min == other._min
32 && _max == other._max;
33 }
34 }
35
36 /**
37 * A greedy parser that repeatedly parses between 'min' and 'max' instances of
38 * its delegate.
39 */
40 class PossessiveRepeatingParser extends RepeatingParser {
41 PossessiveRepeatingParser(Parser parser, int min, int max)
42 : super(parser, min, max);
43
44 @override
45 Result parseOn(Context context) {
46 var current = context;
47 var elements = new List();
48 while (elements.length < _min) {
49 var result = _delegate.parseOn(current);
50 if (result.isFailure) {
51 return result;
52 }
53 elements.add(result.value);
54 current = result;
55 }
56 while (_max == unbounded || elements.length < _max) {
57 var result = _delegate.parseOn(current);
58 if (result.isFailure) {
59 return current.success(elements);
60 }
61 elements.add(result.value);
62 current = result;
63 }
64 return current.success(elements);
65 }
66
67 @override
68 Parser copy() => new PossessiveRepeatingParser(_delegate, _min, _max);
69 }
70
71 /**
72 * An abstract parser that repeatedly parses between 'min' and 'max' instances o f
73 * its delegate and that requires the input to be completed with a specified par ser
74 * 'limit'. Subclasses provide repeating behavior as typically seen in regular
75 * expression implementations (non-blind).
76 */
77 abstract class LimitedRepeatingParser extends RepeatingParser {
78 Parser _limit;
79
80 LimitedRepeatingParser(Parser parser, this._limit, int min, int max)
81 : super(parser, min, max);
82
83 @override
84 List<Parser> get children => [_delegate, _limit];
85
86 @override
87 void replace(Parser source, Parser target) {
88 super.replace(source, target);
89 if (_limit == source) {
90 _limit = target;
91 }
92 }
93 }
94
95 /**
96 * A greedy repeating parser, commonly seen in regular expression implementation s. It
97 * aggressively consumes as much input as possible and then backtracks to meet t he
98 * 'limit' condition.
99 */
100 class GreedyRepeatingParser extends LimitedRepeatingParser {
101 GreedyRepeatingParser(Parser parser, Parser limit, int min, int max)
102 : super(parser, limit, min, max);
103
104 @override
105 Result parseOn(Context context) {
106 var current = context;
107 var elements = new List();
108 while (elements.length < _min) {
109 var result = _delegate.parseOn(current);
110 if (result.isFailure) {
111 return result;
112 }
113 elements.add(result.value);
114 current = result;
115 }
116 var contexts = new List.from([current]);
117 while (_max == unbounded || elements.length < _max) {
118 var result = _delegate.parseOn(current);
119 if (result.isFailure) {
120 break;
121 }
122 elements.add(result.value);
123 contexts.add(current = result);
124 }
125 while (true) {
126 var limit = _limit.parseOn(contexts.last);
127 if (limit.isSuccess) {
128 return contexts.last.success(elements);
129 }
130 if (elements.isEmpty) {
131 return limit;
132 }
133 contexts.removeLast();
134 elements.removeLast();
135 if (contexts.isEmpty) {
136 return limit;
137 }
138 }
139 }
140
141 @override
142 Parser copy() => new GreedyRepeatingParser(_delegate, _limit, _min, _max);
143 }
144
145 /**
146 * A lazy repeating parser, commonly seen in regular expression implementations. It
147 * limits its consumption to meet the 'limit' condition as early as possible.
148 */
149 class LazyRepeatingParser extends LimitedRepeatingParser {
150 LazyRepeatingParser(Parser parser, Parser limit, int min, int max)
151 : super(parser, limit, min, max);
152
153 @override
154 Result parseOn(Context context) {
155 var current = context;
156 var elements = new List();
157 while (elements.length < _min) {
158 var result = _delegate.parseOn(current);
159 if (result.isFailure) {
160 return result;
161 }
162 elements.add(result.value);
163 current = result;
164 }
165 while (true) {
166 var limit = _limit.parseOn(current);
167 if (limit.isSuccess) {
168 return current.success(elements);
169 } else {
170 if (_max != unbounded && elements.length >= _max) {
171 return limit;
172 }
173 var result = _delegate.parseOn(current);
174 if (result.isFailure) {
175 return limit;
176 }
177 elements.add(result.value);
178 current = result;
179 }
180 }
181 }
182
183 @override
184 Parser copy() => new LazyRepeatingParser(_delegate, _limit, _min, _max);
185 }
OLDNEW
« no previous file with comments | « petitparser/lib/src/core/predicates.dart ('k') | petitparser/lib/src/core/token.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698