OLD | NEW |
1 part of reflection; | 1 part of petitparser.reflection; |
2 | 2 |
3 /** | 3 /// A function transforming one parser to another one. |
4 * A function transforming one parser to another one. | |
5 */ | |
6 typedef Parser TransformationHandler(Parser parser); | 4 typedef Parser TransformationHandler(Parser parser); |
7 | 5 |
8 /** | 6 /// Transforms all parsers reachable from [parser] with the given [handler]. |
9 * Transforms all parsers reachable from [parser] with the given [handler]. | 7 /// The identity function returns a copy of the the incoming parser. |
10 * The identity function returns a copy of the the incoming parser. | 8 /// |
11 * | 9 /// The implementation first creates a copy of each parser reachable in the |
12 * The implementation first creates a copy of each parser reachable in the | 10 /// input grammar; then the resulting grammar is traversed until all references |
13 * input grammar; then the resulting grammar is traversed until all references | 11 /// to old parsers are replaced with the transformed ones. |
14 * to old parsers are replaced with the transformed ones. | |
15 */ | |
16 Parser transformParser(Parser parser, TransformationHandler handler) { | 12 Parser transformParser(Parser parser, TransformationHandler handler) { |
17 var mapping = new Map.identity(); | 13 var mapping = new Map.identity(); |
18 for (var each in allParser(parser)) { | 14 for (var each in allParser(parser)) { |
19 mapping[each] = handler(each.copy()); | 15 mapping[each] = handler(each.copy()); |
20 } | 16 } |
21 var seen = new Set.from(mapping.values); | 17 var seen = new Set.from(mapping.values); |
22 var todo = new List.from(mapping.values); | 18 var todo = new List.from(mapping.values); |
23 while (todo.isNotEmpty) { | 19 while (todo.isNotEmpty) { |
24 var parent = todo.removeLast(); | 20 var parent = todo.removeLast(); |
25 for (var child in parent.children) { | 21 for (var child in parent.children) { |
26 if (mapping.containsKey(child)) { | 22 if (mapping.containsKey(child)) { |
27 parent.replace(child, mapping[child]); | 23 parent.replace(child, mapping[child]); |
28 } else if (!seen.contains(child)) { | 24 } else if (!seen.contains(child)) { |
29 seen.add(child); | 25 seen.add(child); |
30 todo.add(child); | 26 todo.add(child); |
31 } | 27 } |
32 } | 28 } |
33 } | 29 } |
34 return mapping[parser]; | 30 return mapping[parser]; |
35 } | 31 } |
OLD | NEW |