OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 /// A library for parsing strings using a sequence of patterns. | 5 /// A library for parsing strings using a sequence of patterns. |
6 library string_scanner; | 6 library string_scanner; |
7 | 7 |
8 import 'dart:math' as math; | 8 import 'dart:math' as math; |
9 | 9 |
| 10 /// When compiled to JS, forward slashes are always escaped in [RegExp.pattern]. |
| 11 /// |
| 12 /// See issue 17998. |
| 13 final _slashAutoEscape = new RegExp("/").pattern == "\\/"; |
| 14 |
10 // TODO(nweiz): Add some integration between this and source maps. | 15 // TODO(nweiz): Add some integration between this and source maps. |
11 /// A class that scans through a string using [Pattern]s. | 16 /// A class that scans through a string using [Pattern]s. |
12 class StringScanner { | 17 class StringScanner { |
13 /// The string being scanned through. | 18 /// The string being scanned through. |
14 final String string; | 19 final String string; |
15 | 20 |
16 /// The current position of the scanner in the string, in characters. | 21 /// The current position of the scanner in the string, in characters. |
17 int get position => _position; | 22 int get position => _position; |
18 set position(int position) { | 23 set position(int position) { |
19 if (position < 0 || position > string.length) { | 24 if (position < 0 || position > string.length) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 /// | 63 /// |
59 /// If [pattern] did not match, throws a [FormatException] describing the | 64 /// If [pattern] did not match, throws a [FormatException] describing the |
60 /// position of the failure. [name] is used in this error as the expected name | 65 /// position of the failure. [name] is used in this error as the expected name |
61 /// of the pattern being matched; if it's `null`, the pattern itself is used | 66 /// of the pattern being matched; if it's `null`, the pattern itself is used |
62 /// instead. | 67 /// instead. |
63 void expect(Pattern pattern, {String name}) { | 68 void expect(Pattern pattern, {String name}) { |
64 if (scan(pattern)) return; | 69 if (scan(pattern)) return; |
65 | 70 |
66 if (name == null) { | 71 if (name == null) { |
67 if (pattern is RegExp) { | 72 if (pattern is RegExp) { |
68 name = "/${pattern.pattern.replaceAll("/", "\\/")}/"; | 73 var source = pattern.pattern; |
| 74 if (!_slashAutoEscape) source = source.replaceAll("/", "\\/"); |
| 75 name = "/$source/"; |
69 } else { | 76 } else { |
70 name = pattern.toString() | 77 name = pattern.toString() |
71 .replaceAll("\\", "\\\\").replaceAll('"', '\\"'); | 78 .replaceAll("\\", "\\\\").replaceAll('"', '\\"'); |
72 name = '"$name"'; | 79 name = '"$name"'; |
73 } | 80 } |
74 } | 81 } |
75 _fail(name); | 82 _fail(name); |
76 } | 83 } |
77 | 84 |
78 /// If the string has not been fully consumed, this throws a | 85 /// If the string has not been fully consumed, this throws a |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 "$spaces$underline"); | 160 "$spaces$underline"); |
154 } | 161 } |
155 | 162 |
156 // TODO(nweiz): Make this handle long lines more gracefully. | 163 // TODO(nweiz): Make this handle long lines more gracefully. |
157 /// Throws a [FormatException] describing that [name] is expected at the | 164 /// Throws a [FormatException] describing that [name] is expected at the |
158 /// current position in the string. | 165 /// current position in the string. |
159 void _fail(String name) { | 166 void _fail(String name) { |
160 error("expected $name.", position: this.position, length: 1); | 167 error("expected $name.", position: this.position, length: 1); |
161 } | 168 } |
162 } | 169 } |
OLD | NEW |