| 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 |