| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 part of scanner; | 5 part of scanner; |
| 6 | 6 |
| 7 abstract class ArrayBasedScanner extends AbstractScanner { | 7 abstract class ArrayBasedScanner extends AbstractScanner { |
| 8 ArrayBasedScanner(SourceFile file, bool includeComments) | 8 ArrayBasedScanner(SourceFile file, bool includeComments) |
| 9 : super(file, includeComments); | 9 : super(file, includeComments); |
| 10 | 10 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 // Type parameters and arguments cannot contain 'this' or 'super'. | 65 // Type parameters and arguments cannot contain 'this' or 'super'. |
| 66 if (identical(syntax, 'this') || identical(syntax, 'super')) { | 66 if (identical(syntax, 'this') || identical(syntax, 'super')) { |
| 67 discardOpenLt(); | 67 discardOpenLt(); |
| 68 } | 68 } |
| 69 tail.next = new KeywordToken(keyword, tokenStart); | 69 tail.next = new KeywordToken(keyword, tokenStart); |
| 70 tail = tail.next; | 70 tail = tail.next; |
| 71 } | 71 } |
| 72 | 72 |
| 73 void appendEofToken() { | 73 void appendEofToken() { |
| 74 beginToken(); | 74 beginToken(); |
| 75 tail.next = new SymbolToken(EOF_INFO, tokenStart); | |
| 76 tail = tail.next; | |
| 77 // EOF points to itself so there's always infinite look-ahead. | |
| 78 tail.next = tail; | |
| 79 discardOpenLt(); | 75 discardOpenLt(); |
| 80 while (!groupingStack.isEmpty) { | 76 while (!groupingStack.isEmpty) { |
| 81 unmatchedBeginGroup(groupingStack.head); | 77 unmatchedBeginGroup(groupingStack.head); |
| 82 groupingStack = groupingStack.tail; | 78 groupingStack = groupingStack.tail; |
| 83 } | 79 } |
| 80 tail.next = new SymbolToken(EOF_INFO, tokenStart); |
| 81 tail = tail.next; |
| 82 // EOF points to itself so there's always infinite look-ahead. |
| 83 tail.next = tail; |
| 84 } | 84 } |
| 85 | 85 |
| 86 /** | 86 /** |
| 87 * Notifies scanning a whitespace character. Note that [appendWhiteSpace] is | 87 * Notifies scanning a whitespace character. Note that [appendWhiteSpace] is |
| 88 * not always invoked for [$SPACE] characters. | 88 * not always invoked for [$SPACE] characters. |
| 89 * | 89 * |
| 90 * This method is used by the scanners to track line breaks and create the | 90 * This method is used by the scanners to track line breaks and create the |
| 91 * [lineStarts] map. | 91 * [lineStarts] map. |
| 92 */ | 92 */ |
| 93 void appendWhiteSpace(int next) { | 93 void appendWhiteSpace(int next) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 122 groupingStack = groupingStack.prepend(token); | 122 groupingStack = groupingStack.prepend(token); |
| 123 } | 123 } |
| 124 | 124 |
| 125 /** | 125 /** |
| 126 * Appends a token that begins an end group, represented by [value]. | 126 * Appends a token that begins an end group, represented by [value]. |
| 127 * It handles the group end tokens '}', ')' and ']'. The tokens '>' and | 127 * It handles the group end tokens '}', ')' and ']'. The tokens '>' and |
| 128 * '>>' are handled separately bo [appendGt] and [appendGtGt]. | 128 * '>>' are handled separately bo [appendGt] and [appendGtGt]. |
| 129 */ | 129 */ |
| 130 int appendEndGroup(PrecedenceInfo info, int openKind) { | 130 int appendEndGroup(PrecedenceInfo info, int openKind) { |
| 131 assert(!identical(openKind, LT_TOKEN)); // openKind is < for > and >> | 131 assert(!identical(openKind, LT_TOKEN)); // openKind is < for > and >> |
| 132 discardBeginGroupUntil(openKind); |
| 132 appendPrecedenceToken(info); | 133 appendPrecedenceToken(info); |
| 133 // Don't report unmatched errors for <; it is also the less-than operator. | 134 Token close = tail; |
| 134 discardOpenLt(); | |
| 135 if (groupingStack.isEmpty) { | 135 if (groupingStack.isEmpty) { |
| 136 return advance(); | 136 return advance(); |
| 137 } | 137 } |
| 138 BeginGroupToken begin = groupingStack.head; | 138 BeginGroupToken begin = groupingStack.head; |
| 139 if (!identical(begin.kind, openKind)) { | 139 if (!identical(begin.kind, openKind)) { |
| 140 if (!identical(openKind, OPEN_CURLY_BRACKET_TOKEN) || | 140 assert(begin.kind == STRING_INTERPOLATION_TOKEN && |
| 141 !identical(begin.kind, STRING_INTERPOLATION_TOKEN)) { | 141 openKind == OPEN_CURLY_BRACKET_TOKEN); |
| 142 // Not ending string interpolation. | |
| 143 unmatchedBeginGroup(begin); | |
| 144 return advance(); | |
| 145 } | |
| 146 // We're ending an interpolated expression. | 142 // We're ending an interpolated expression. |
| 147 begin.endGroup = tail; | 143 begin.endGroup = close; |
| 148 groupingStack = groupingStack.tail; | 144 groupingStack = groupingStack.tail; |
| 149 // Using "start-of-text" to signal that we're back in string | 145 // Using "start-of-text" to signal that we're back in string |
| 150 // scanning mode. | 146 // scanning mode. |
| 151 return $STX; | 147 return $STX; |
| 152 } | 148 } |
| 153 begin.endGroup = tail; | 149 begin.endGroup = close; |
| 154 groupingStack = groupingStack.tail; | 150 groupingStack = groupingStack.tail; |
| 155 return advance(); | 151 return advance(); |
| 156 } | 152 } |
| 157 | 153 |
| 158 /** | 154 /** |
| 155 * Discards begin group tokens until a match with [openKind] is found. |
| 156 * This recovers nicely from from a situation like "{[}". |
| 157 */ |
| 158 void discardBeginGroupUntil(int openKind) { |
| 159 while (!groupingStack.isEmpty) { |
| 160 // Don't report unmatched errors for <; it is also the less-than operator. |
| 161 discardOpenLt(); |
| 162 if (groupingStack.isEmpty) return; |
| 163 BeginGroupToken begin = groupingStack.head; |
| 164 if (openKind == begin.kind) return; |
| 165 if (openKind == OPEN_CURLY_BRACKET_TOKEN && |
| 166 begin.kind == STRING_INTERPOLATION_TOKEN) return; |
| 167 unmatchedBeginGroup(begin); |
| 168 groupingStack = groupingStack.tail; |
| 169 } |
| 170 } |
| 171 |
| 172 /** |
| 159 * Appends a token for '>'. | 173 * Appends a token for '>'. |
| 160 * This method does not issue unmatched errors, because > is also the | 174 * This method does not issue unmatched errors, because > is also the |
| 161 * greater-than operator. It does not necessarily have to close a group. | 175 * greater-than operator. It does not necessarily have to close a group. |
| 162 */ | 176 */ |
| 163 void appendGt(PrecedenceInfo info) { | 177 void appendGt(PrecedenceInfo info) { |
| 164 appendPrecedenceToken(info); | 178 appendPrecedenceToken(info); |
| 165 if (groupingStack.isEmpty) return; | 179 if (groupingStack.isEmpty) return; |
| 166 if (identical(groupingStack.head.kind, LT_TOKEN)) { | 180 if (identical(groupingStack.head.kind, LT_TOKEN)) { |
| 167 groupingStack.head.endGroup = tail; | 181 groupingStack.head.endGroup = tail; |
| 168 groupingStack = groupingStack.tail; | 182 groupingStack = groupingStack.tail; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 * something which cannot possibly be part of a type parameter/argument | 224 * something which cannot possibly be part of a type parameter/argument |
| 211 * list, like the '=' in the above example. | 225 * list, like the '=' in the above example. |
| 212 */ | 226 */ |
| 213 void discardOpenLt() { | 227 void discardOpenLt() { |
| 214 while (!groupingStack.isEmpty | 228 while (!groupingStack.isEmpty |
| 215 && identical(groupingStack.head.kind, LT_TOKEN)) { | 229 && identical(groupingStack.head.kind, LT_TOKEN)) { |
| 216 groupingStack = groupingStack.tail; | 230 groupingStack = groupingStack.tail; |
| 217 } | 231 } |
| 218 } | 232 } |
| 219 } | 233 } |
| OLD | NEW |