OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 library test.backend.platform_selector.scanner; | 5 library test.backend.platform_selector.scanner; |
6 | 6 |
7 import 'package:string_scanner/string_scanner.dart'; | 7 import 'package:string_scanner/string_scanner.dart'; |
8 | 8 |
| 9 import '../../utils.dart'; |
9 import 'token.dart'; | 10 import 'token.dart'; |
10 | 11 |
11 /// A regular expression matching both whitespace and single-line comments. | 12 /// A regular expression matching both whitespace and single-line comments. |
12 /// | 13 /// |
13 /// This will only match if consumes at least one character. | 14 /// This will only match if consumes at least one character. |
14 final _whitespaceAndSingleLineComments = | 15 final _whitespaceAndSingleLineComments = |
15 new RegExp(r"([ \t\n]+|//[^\n]*(\n|$))+"); | 16 new RegExp(r"([ \t\n]+|//[^\n]*(\n|$))+"); |
16 | 17 |
17 /// A regular expression matching the body of a multi-line comment, after `/*` | 18 /// A regular expression matching the body of a multi-line comment, after `/*` |
18 /// but before `*/` or a nested `/*`. | 19 /// but before `*/` or a nested `/*`. |
19 /// | 20 /// |
20 /// This will only match if it consumes at least one character. | 21 /// This will only match if it consumes at least one character. |
21 final _multiLineCommentBody = new RegExp(r"([^/*]|/[^*]|\*[^/])+"); | 22 final _multiLineCommentBody = new RegExp(r"([^/*]|/[^*]|\*[^/])+"); |
22 | 23 |
23 /// A regular expression matching an identifier. | |
24 /// | |
25 /// Unlike standard Dart identifiers, platform selector identifiers may | |
26 /// contain dashes for consistency with command-line arguments. | |
27 final _identifier = new RegExp(r"[a-zA-Z_-][a-zA-Z0-9_-]*"); | |
28 | |
29 /// A scanner that converts a platform selector string into a stream of | 24 /// A scanner that converts a platform selector string into a stream of |
30 /// tokens. | 25 /// tokens. |
31 class Scanner { | 26 class Scanner { |
32 /// The underlying string scanner. | 27 /// The underlying string scanner. |
33 final SpanScanner _scanner; | 28 final SpanScanner _scanner; |
34 | 29 |
35 /// The next token to emit. | 30 /// The next token to emit. |
36 Token _next; | 31 Token _next; |
37 | 32 |
38 /// Whether the scanner has emitted a [TokenType.endOfFile] token. | 33 /// Whether the scanner has emitted a [TokenType.endOfFile] token. |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 /// | 112 /// |
118 /// This validates that the next two characters are `&&`. | 113 /// This validates that the next two characters are `&&`. |
119 Token _scanAnd() { | 114 Token _scanAnd() { |
120 var start = _scanner.state; | 115 var start = _scanner.state; |
121 _scanner.expect("&&"); | 116 _scanner.expect("&&"); |
122 return new Token(TokenType.and, _scanner.spanFrom(start)); | 117 return new Token(TokenType.and, _scanner.spanFrom(start)); |
123 } | 118 } |
124 | 119 |
125 /// Scans and returns an identifier token. | 120 /// Scans and returns an identifier token. |
126 Token _scanIdentifier() { | 121 Token _scanIdentifier() { |
127 _scanner.expect(_identifier, name: "expression"); | 122 _scanner.expect(hyphenatedIdentifier, name: "expression"); |
128 return new IdentifierToken(_scanner.lastMatch[0], _scanner.lastSpan); | 123 return new IdentifierToken(_scanner.lastMatch[0], _scanner.lastSpan); |
129 } | 124 } |
130 | 125 |
131 /// Consumes all whitespace and comments immediately following the cursor's | 126 /// Consumes all whitespace and comments immediately following the cursor's |
132 /// current position. | 127 /// current position. |
133 void _consumeWhitespace() { | 128 void _consumeWhitespace() { |
134 while (_scanner.scan(_whitespaceAndSingleLineComments) || | 129 while (_scanner.scan(_whitespaceAndSingleLineComments) || |
135 _multiLineComment()) { | 130 _multiLineComment()) { |
136 // Do nothing. | 131 // Do nothing. |
137 } | 132 } |
138 } | 133 } |
139 | 134 |
140 /// Consumes a single multi-line comment. | 135 /// Consumes a single multi-line comment. |
141 /// | 136 /// |
142 /// Returns whether or not a comment was consumed. | 137 /// Returns whether or not a comment was consumed. |
143 bool _multiLineComment() { | 138 bool _multiLineComment() { |
144 if (!_scanner.scan("/*")) return false; | 139 if (!_scanner.scan("/*")) return false; |
145 | 140 |
146 while (_scanner.scan(_multiLineCommentBody) || _multiLineComment()) { | 141 while (_scanner.scan(_multiLineCommentBody) || _multiLineComment()) { |
147 // Do nothing. | 142 // Do nothing. |
148 } | 143 } |
149 _scanner.expect("*/"); | 144 _scanner.expect("*/"); |
150 | 145 |
151 return true; | 146 return true; |
152 } | 147 } |
153 } | 148 } |
OLD | NEW |