OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 fasta.parser.parser; | 5 library fasta.parser.parser; |
6 | 6 |
7 import '../fasta_codes.dart' | 7 import '../fasta_codes.dart' |
8 show | 8 show |
9 FastaCode, | 9 FastaCode, |
10 FastaMessage, | 10 FastaMessage, |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 import '../scanner/recover.dart' show closeBraceFor, skipToEof; | 70 import '../scanner/recover.dart' show closeBraceFor, skipToEof; |
71 | 71 |
72 import '../../scanner/token.dart' | 72 import '../../scanner/token.dart' |
73 show | 73 show |
74 ASSIGNMENT_PRECEDENCE, | 74 ASSIGNMENT_PRECEDENCE, |
75 BeginToken, | 75 BeginToken, |
76 CASCADE_PRECEDENCE, | 76 CASCADE_PRECEDENCE, |
77 EQUALITY_PRECEDENCE, | 77 EQUALITY_PRECEDENCE, |
78 POSTFIX_PRECEDENCE, | 78 POSTFIX_PRECEDENCE, |
79 RELATIONAL_PRECEDENCE, | 79 RELATIONAL_PRECEDENCE, |
| 80 SyntheticStringToken, |
80 TokenType; | 81 TokenType; |
81 | 82 |
82 import '../scanner/token.dart' show isUserDefinableOperator; | 83 import '../scanner/token.dart' show isUserDefinableOperator; |
83 | 84 |
84 import '../scanner/token_constants.dart' | 85 import '../scanner/token_constants.dart' |
85 show | 86 show |
86 COMMA_TOKEN, | 87 COMMA_TOKEN, |
87 DOUBLE_TOKEN, | 88 DOUBLE_TOKEN, |
88 EOF_TOKEN, | 89 EOF_TOKEN, |
89 EQ_TOKEN, | 90 EQ_TOKEN, |
(...skipping 17 matching lines...) Expand all Loading... |
107 | 108 |
108 import '../scanner/characters.dart' show $CLOSE_CURLY_BRACKET; | 109 import '../scanner/characters.dart' show $CLOSE_CURLY_BRACKET; |
109 | 110 |
110 import '../util/link.dart' show Link; | 111 import '../util/link.dart' show Link; |
111 | 112 |
112 import 'async_modifier.dart' show AsyncModifier; | 113 import 'async_modifier.dart' show AsyncModifier; |
113 | 114 |
114 import 'listener.dart' show Listener; | 115 import 'listener.dart' show Listener; |
115 | 116 |
116 import 'identifier_context.dart' show IdentifierContext; | 117 import 'identifier_context.dart' show IdentifierContext; |
| 118 import 'package:front_end/src/fasta/parser/token_stream_rewriter.dart'; |
117 | 119 |
118 /// Returns true if [token] is the symbol or keyword [value]. | 120 /// Returns true if [token] is the symbol or keyword [value]. |
119 bool optional(String value, Token token) { | 121 bool optional(String value, Token token) { |
120 return identical(value, token.stringValue); | 122 return identical(value, token.stringValue); |
121 } | 123 } |
122 | 124 |
123 class FormalParameterType { | 125 class FormalParameterType { |
124 final String type; | 126 final String type; |
125 const FormalParameterType(this.type); | 127 const FormalParameterType(this.type); |
126 bool get isRequired => this == REQUIRED; | 128 bool get isRequired => this == REQUIRED; |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 /// modifiers such as `abstract`, `final`, `static`, etc. Historically, dart2js | 305 /// modifiers such as `abstract`, `final`, `static`, etc. Historically, dart2js |
304 /// would handle such errors in later phases. We hope that these cases will go | 306 /// would handle such errors in later phases. We hope that these cases will go |
305 /// away as Fasta matures. | 307 /// away as Fasta matures. |
306 class Parser { | 308 class Parser { |
307 final Listener listener; | 309 final Listener listener; |
308 | 310 |
309 Uri get uri => listener.uri; | 311 Uri get uri => listener.uri; |
310 | 312 |
311 bool mayParseFunctionExpressions = true; | 313 bool mayParseFunctionExpressions = true; |
312 | 314 |
| 315 TokenStreamRewriter _rewriter; |
| 316 |
313 /// Represents parser state: what asynchronous syntax is allowed in the | 317 /// Represents parser state: what asynchronous syntax is allowed in the |
314 /// function being currently parsed. In rare situations, this can be set by | 318 /// function being currently parsed. In rare situations, this can be set by |
315 /// external clients, for example, to parse an expression outside a function. | 319 /// external clients, for example, to parse an expression outside a function. |
316 AsyncModifier asyncState = AsyncModifier.Sync; | 320 AsyncModifier asyncState = AsyncModifier.Sync; |
317 | 321 |
318 Parser(this.listener); | 322 Parser(this.listener); |
319 | 323 |
320 bool get inGenerator { | 324 bool get inGenerator { |
321 return asyncState == AsyncModifier.AsyncStar || | 325 return asyncState == AsyncModifier.AsyncStar || |
322 asyncState == AsyncModifier.SyncStar; | 326 asyncState == AsyncModifier.SyncStar; |
323 } | 327 } |
324 | 328 |
325 bool get inAsync { | 329 bool get inAsync { |
326 return asyncState == AsyncModifier.Async || | 330 return asyncState == AsyncModifier.Async || |
327 asyncState == AsyncModifier.AsyncStar; | 331 asyncState == AsyncModifier.AsyncStar; |
328 } | 332 } |
329 | 333 |
330 bool get inPlainSync => asyncState == AsyncModifier.Sync; | 334 bool get inPlainSync => asyncState == AsyncModifier.Sync; |
331 | 335 |
332 Token parseUnit(Token token) { | 336 Token parseUnit(Token token) { |
| 337 _rewriter = new TokenStreamRewriter(token); |
333 listener.beginCompilationUnit(token); | 338 listener.beginCompilationUnit(token); |
334 int count = 0; | 339 int count = 0; |
335 while (!identical(token.kind, EOF_TOKEN)) { | 340 while (!identical(token.kind, EOF_TOKEN)) { |
336 token = parseTopLevelDeclaration(token); | 341 token = parseTopLevelDeclaration(token); |
337 count++; | 342 count++; |
338 } | 343 } |
339 listener.endCompilationUnit(count, token); | 344 listener.endCompilationUnit(count, token); |
340 return token; | 345 return token; |
341 } | 346 } |
342 | 347 |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
452 } | 457 } |
453 listener.endDottedName(count, firstIdentifier); | 458 listener.endDottedName(count, firstIdentifier); |
454 return token; | 459 return token; |
455 } | 460 } |
456 | 461 |
457 /// export uri conditional-uris* combinator* ';' | 462 /// export uri conditional-uris* combinator* ';' |
458 Token parseExport(Token token) { | 463 Token parseExport(Token token) { |
459 Token exportKeyword = token; | 464 Token exportKeyword = token; |
460 listener.beginExport(exportKeyword); | 465 listener.beginExport(exportKeyword); |
461 assert(optional('export', token)); | 466 assert(optional('export', token)); |
462 token = parseLiteralStringOrRecoverExpression(token.next); | 467 token = parseLiteralString(ensureLiteralString(token.next)); |
463 token = parseConditionalUris(token); | 468 token = parseConditionalUris(token); |
464 token = parseCombinators(token); | 469 token = parseCombinators(token); |
465 Token semicolon = token; | 470 Token semicolon = token; |
466 token = expect(';', token); | 471 token = expect(';', token); |
467 listener.endExport(exportKeyword, semicolon); | 472 listener.endExport(exportKeyword, semicolon); |
468 return token; | 473 return token; |
469 } | 474 } |
470 | 475 |
471 Token parseCombinators(Token token) { | 476 Token parseCombinators(Token token) { |
472 listener.beginCombinators(token); | 477 listener.beginCombinators(token); |
(...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1078 } else if (optional('yield', token)) { | 1083 } else if (optional('yield', token)) { |
1079 reportRecoverableErrorCode(token, codeYieldAsIdentifier); | 1084 reportRecoverableErrorCode(token, codeYieldAsIdentifier); |
1080 } else if (optional('async', token)) { | 1085 } else if (optional('async', token)) { |
1081 reportRecoverableErrorCode(token, codeAsyncAsIdentifier); | 1086 reportRecoverableErrorCode(token, codeAsyncAsIdentifier); |
1082 } | 1087 } |
1083 } | 1088 } |
1084 listener.handleIdentifier(token, context); | 1089 listener.handleIdentifier(token, context); |
1085 return token.next; | 1090 return token.next; |
1086 } | 1091 } |
1087 | 1092 |
| 1093 Token ensureLiteralString(Token token) { |
| 1094 if (!identical(token.kind, STRING_TOKEN)) { |
| 1095 print('>>> ensureLiteralString'); |
| 1096 reportRecoverableErrorCodeWithToken(token, codeExpectedString); |
| 1097 token = _rewriter.insertTokenBefore( |
| 1098 new SyntheticStringToken(TokenType.STRING, '""', token.offset, 0), |
| 1099 token); |
| 1100 } |
| 1101 return token; |
| 1102 } |
| 1103 |
1088 Token expect(String string, Token token) { | 1104 Token expect(String string, Token token) { |
1089 if (!identical(string, token.stringValue)) { | 1105 if (!identical(string, token.stringValue)) { |
1090 return reportUnrecoverableErrorCodeWithString( | 1106 return reportUnrecoverableErrorCodeWithString( |
1091 token, codeExpectedButGot, string) | 1107 token, codeExpectedButGot, string) |
1092 .next; | 1108 .next; |
1093 } | 1109 } |
1094 return token.next; | 1110 return token.next; |
1095 } | 1111 } |
1096 | 1112 |
1097 Token parseTypeVariable(Token token) { | 1113 Token parseTypeVariable(Token token) { |
(...skipping 2927 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4025 return reportUnrecoverableError( | 4041 return reportUnrecoverableError( |
4026 token, () => code.format(uri, token.charOffset, string)); | 4042 token, () => code.format(uri, token.charOffset, string)); |
4027 } | 4043 } |
4028 } | 4044 } |
4029 | 4045 |
4030 typedef FastaMessage NoArgument(Uri uri, int charOffset); | 4046 typedef FastaMessage NoArgument(Uri uri, int charOffset); |
4031 | 4047 |
4032 typedef FastaMessage TokenArgument(Uri uri, int charOffset, Token token); | 4048 typedef FastaMessage TokenArgument(Uri uri, int charOffset, Token token); |
4033 | 4049 |
4034 typedef FastaMessage StringArgument(Uri uri, int charOffset, String string); | 4050 typedef FastaMessage StringArgument(Uri uri, int charOffset, String string); |
OLD | NEW |