OLD | NEW |
| (Empty) |
1 part of dart; | |
2 | |
3 /** | |
4 * Dart grammar. | |
5 */ | |
6 class DartGrammar extends GrammarParser { | |
7 DartGrammar() : super(new DartGrammarDefinition()); | |
8 } | |
9 | |
10 /** | |
11 * Dart grammar definition. | |
12 * | |
13 * Adapted from [https://code.google.com/p/dart/source/browse/branches/bleeding_
edge/dart/language/grammar/Dart.g]. | |
14 */ | |
15 class DartGrammarDefinition extends GrammarDefinition { | |
16 | |
17 Parser token(input) { | |
18 if (input is String) { | |
19 input = input.length == 1 ? char(input) : string(input); | |
20 } else if (input is Function) { | |
21 input = ref(input); | |
22 } | |
23 if (input is! Parser && input is TrimmingParser) { | |
24 throw new StateError('Invalid token parser: $input'); | |
25 } | |
26 return input.token().trim(ref(HIDDEN)); | |
27 } | |
28 | |
29 | |
30 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | |
31 // for details. All rights reserved. Use of this source code is governed by a | |
32 // BSD-style license that can be found in the LICENSE file. | |
33 | |
34 // ----------------------------------------------------------------- | |
35 // Keyword definitions. | |
36 // ----------------------------------------------------------------- | |
37 BREAK() => ref(token, 'break'); | |
38 CASE() => ref(token, 'case'); | |
39 CATCH() => ref(token, 'catch'); | |
40 CONST() => ref(token, 'const'); | |
41 CONTINUE() => ref(token, 'continue'); | |
42 DEFAULT() => ref(token, 'default'); | |
43 DO() => ref(token, 'do'); | |
44 ELSE() => ref(token, 'else'); | |
45 FALSE() => ref(token, 'false'); | |
46 FINAL() => ref(token, 'final'); | |
47 FINALLY() => ref(token, 'finally'); | |
48 FOR() => ref(token, 'for'); | |
49 IF() => ref(token, 'if'); | |
50 IN() => ref(token, 'in'); | |
51 NEW() => ref(token, 'new'); | |
52 NULL() => ref(token, 'null'); | |
53 RETURN() => ref(token, 'return'); | |
54 SUPER() => ref(token, 'super'); | |
55 SWITCH() => ref(token, 'switch'); | |
56 THIS() => ref(token, 'this'); | |
57 THROW() => ref(token, 'throw'); | |
58 TRUE() => ref(token, 'true'); | |
59 TRY() => ref(token, 'try'); | |
60 VAR() => ref(token, 'var'); | |
61 VOID() => ref(token, 'void'); | |
62 WHILE() => ref(token, 'while'); | |
63 | |
64 // Pseudo-keywords that should also be valid identifiers. | |
65 ABSTRACT() => ref(token, 'abstract'); | |
66 ASSERT() => ref(token, 'assert'); | |
67 CLASS() => ref(token, 'class'); | |
68 EXTENDS() => ref(token, 'extends'); | |
69 FACTORY() => ref(token, 'factory'); | |
70 GET() => ref(token, 'get'); | |
71 IMPLEMENTS() => ref(token, 'implements'); | |
72 IMPORT() => ref(token, 'import'); | |
73 INTERFACE() => ref(token, 'interface'); | |
74 IS() => ref(token, 'is'); | |
75 LIBRARY() => ref(token, 'library'); | |
76 NATIVE() => ref(token, 'native'); | |
77 NEGATE() => ref(token, 'negate'); | |
78 OPERATOR() => ref(token, 'operator'); | |
79 SET() => ref(token, 'set'); | |
80 SOURCE() => ref(token, 'source'); | |
81 STATIC() => ref(token, 'static'); | |
82 TYPEDEF() => ref(token, 'typedef'); | |
83 | |
84 // ----------------------------------------------------------------- | |
85 // Grammar productions. | |
86 // ----------------------------------------------------------------- | |
87 start() => ref(compilationUnit).end(); | |
88 | |
89 compilationUnit() => | |
90 ref(HASHBANG).optional() | |
91 & ref(directive).star() | |
92 & ref(topLevelDefinition).star(); | |
93 | |
94 directive() => | |
95 ref(token, '#') | |
96 & ref(identifier) | |
97 & ref(arguments) | |
98 & ref(token, ';'); | |
99 | |
100 topLevelDefinition() => | |
101 ref(classDefinition) | |
102 | ref(interfaceDefinition) | |
103 | ref(functionTypeAlias) | |
104 | ref(functionDeclaration) & ref(functionBodyOrNative) | |
105 | ref(returnType).optional() & ref(getOrSet) & ref(identifier) & ref(forma
lParameterList) & ref(functionBodyOrNative) | |
106 | ref(FINAL) & ref(type).optional() & ref(staticFinalDeclarationList) & re
f(token, ';') | |
107 | ref(constInitializedVariableDeclaration) & ref(token, ';'); | |
108 | |
109 classDefinition() => | |
110 ref(CLASS) & ref(identifier) & ref(typeParameters).optional() & ref(supe
rclass).optional() & ref(interfaces).optional() & | |
111 ref(token, '{') & ref(classMemberDefinition).star() & ref(token, '}') | |
112 | ref(CLASS) & ref(identifier) & ref(typeParameters).optional() & ref(inte
rfaces).optional() & ref(NATIVE) & ref(token, STRING) & | |
113 ref(token, '{') & ref(classMemberDefinition).star() & ref(token, '}'); | |
114 | |
115 typeParameter() => ref(identifier) & (ref(EXTENDS) & ref(type)).optional(); | |
116 | |
117 typeParameters() => ref(token, '<') & ref(typeParameter) & (ref(token, ',') &
ref(typeParameter)).star() & ref(token, '>'); | |
118 | |
119 superclass() => ref(EXTENDS) & ref(type); | |
120 | |
121 interfaces() => ref(IMPLEMENTS) & ref(typeList); | |
122 | |
123 superinterfaces() => ref(EXTENDS) & ref(typeList); | |
124 | |
125 // This rule is organized in a way that may not be most readable, but | |
126 // gives the best error messages. | |
127 classMemberDefinition() => | |
128 ref(declaration) & ref(token, ';') | |
129 | ref(constructorDeclaration) & ref(token, ';') | |
130 | ref(methodDeclaration) & ref(functionBodyOrNative) | |
131 | ref(CONST) & ref(factoryConstructorDeclaration) & ref(functionNative); | |
132 | |
133 functionBodyOrNative() => | |
134 ref(NATIVE) & ref(functionBody) | |
135 | ref(functionNative) | |
136 | ref(functionBody); | |
137 | |
138 functionNative() => ref(NATIVE) & ref(token, STRING).optional() & ref(token, '
;'); | |
139 | |
140 // A method, operator, or constructor (which all should be followed by | |
141 // a block of code). | |
142 methodDeclaration() => | |
143 ref(factoryConstructorDeclaration) | |
144 | ref(STATIC) & ref(functionDeclaration) | |
145 | ref(specialSignatureDefinition) | |
146 | ref(functionDeclaration) & ref(initializers).optional() | |
147 | ref(namedConstructorDeclaration) & ref(initializers).optional(); | |
148 | |
149 // An abstract method/operator, a field, or const constructor (which | |
150 // all should be followed by a semicolon). | |
151 declaration() => | |
152 ref(constantConstructorDeclaration) & (ref(redirection) | ref(initialize
rs)).optional() | |
153 | ref(functionDeclaration) & ref(redirection) | |
154 | ref(namedConstructorDeclaration) & ref(redirection) | |
155 | ref(ABSTRACT) & ref(specialSignatureDefinition) | |
156 | ref(ABSTRACT) & ref(functionDeclaration) | |
157 | ref(STATIC) & ref(FINAL) & ref(type).optional() & ref(staticFinalDeclara
tionList) | |
158 | ref(STATIC).optional() & ref(constInitializedVariableDeclaration); | |
159 | |
160 initializers() => ref(token, ':') & ref(superCallOrFieldInitializer) & (ref(to
ken, ',') & ref(superCallOrFieldInitializer)).star(); | |
161 | |
162 redirection() => ref(token, ':') & ref(THIS) & (ref(token, '.') & ref(identifi
er)).optional() & ref(arguments); | |
163 | |
164 fieldInitializer() => (ref(THIS) & ref(token, '.')).optional() & ref(identifie
r) & ref(token, '=') & ref(conditionalExpression); | |
165 | |
166 superCallOrFieldInitializer() => | |
167 ref(SUPER) & ref(arguments) | |
168 | ref(SUPER) & ref(token, '.') & ref(identifier) & ref(arguments) | |
169 | ref(fieldInitializer); | |
170 | |
171 staticFinalDeclarationList() => ref(staticFinalDeclaration) & (ref(token, ',')
& ref(staticFinalDeclaration)).star(); | |
172 | |
173 staticFinalDeclaration() => ref(identifier) & ref(token, '=') & ref(constantEx
pression); | |
174 | |
175 interfaceDefinition() => ref(INTERFACE) & ref(identifier) & ref(typeParameters
).optional() & | |
176 ref(superinterfaces).optional() & ref(factorySpecification).optional() & r
ef(token, '{') & | |
177 ref(interfaceMemberDefinition).star() & ref(token, '}'); | |
178 | |
179 factorySpecification() => ref(FACTORY) & ref(type); | |
180 | |
181 functionTypeAlias() => ref(TYPEDEF) & ref(functionPrefix) & ref(typeParameters
).optional() & | |
182 ref(formalParameterList) & ref(token, ';'); | |
183 | |
184 interfaceMemberDefinition() => | |
185 ref(STATIC) & ref(FINAL) & ref(type).optional() & ref(initializedIdentif
ierList) & ref(token, ';') | |
186 | ref(functionDeclaration) & ref(token, ';') | |
187 | ref(constantConstructorDeclaration) & ref(token, ';') | |
188 | ref(namedConstructorDeclaration) & ref(token, ';') | |
189 | ref(specialSignatureDefinition) & ref(token, ';') | |
190 | ref(variableDeclaration) & ref(token, ';'); | |
191 | |
192 factoryConstructorDeclaration() => ref(FACTORY) & ref(qualified) & ref(typePar
ameters).optional() & | |
193 (ref(token, '.') & ref(identifier)).optional() & ref(formalParameterList); | |
194 | |
195 namedConstructorDeclaration() => ref(identifier) & ref(token, '.') & ref(ident
ifier) & | |
196 ref(formalParameterList); | |
197 | |
198 constructorDeclaration() => | |
199 ref(identifier) & ref(formalParameterList) & (ref(redirection) | ref(ini
tializers)).optional() | |
200 | ref(namedConstructorDeclaration) & (ref(redirection) | ref(initializers)
).optional(); | |
201 | |
202 constantConstructorDeclaration() => ref(CONST) & ref(qualified) & ref(formalPa
rameterList); | |
203 | |
204 specialSignatureDefinition() => | |
205 ref(STATIC).optional() & ref(returnType).optional() & ref(getOrSet) & re
f(identifier) & ref(formalParameterList) | |
206 | ref(returnType).optional() & ref(OPERATOR) & ref(userDefinableOperator)
& ref(formalParameterList); | |
207 | |
208 getOrSet() => ref(GET) | ref(SET); | |
209 | |
210 userDefinableOperator() => | |
211 ref(multiplicativeOperator) | |
212 | ref(additiveOperator) | |
213 | ref(shiftOperator) | |
214 | ref(relationalOperator) | |
215 | ref(bitwiseOperator) | |
216 | ref(token, '==') // Disallow negative and === equality checks. | |
217 | ref(token, '~') // Disallow ! operator. | |
218 | ref(NEGATE) | |
219 | ref(token, '[') & ref(token, ']') | |
220 | ref(token, '[') & ref(token, ']') & ref(token, '='); | |
221 | |
222 prefixOperator() => | |
223 ref(additiveOperator) | |
224 | ref(negateOperator); | |
225 | |
226 postfixOperator() => | |
227 ref(incrementOperator); | |
228 | |
229 negateOperator() => | |
230 ref(token, '!') | |
231 | ref(token, '~'); | |
232 | |
233 multiplicativeOperator() => | |
234 ref(token, '*') | |
235 | ref(token, '/') | |
236 | ref(token, '%') | |
237 | ref(token, '~/'); | |
238 | |
239 assignmentOperator() => | |
240 ref(token, '=') | |
241 | ref(token, '*=') | |
242 | ref(token, '/=') | |
243 | ref(token, '~/=') | |
244 | ref(token, '%=') | |
245 | ref(token, '+=') | |
246 | ref(token, '-=') | |
247 | ref(token, '<<=') | |
248 | ref(token, '>') & ref(token, '>') & ref(token, '>') & ref(token, '=') | |
249 | ref(token, '>') & ref(token, '>') & ref(token, '=') | |
250 | ref(token, '&=') | |
251 | ref(token, '^=') | |
252 | ref(token, '|='); | |
253 | |
254 additiveOperator() => | |
255 ref(token, '+') | |
256 | ref(token, '-'); | |
257 | |
258 incrementOperator() => | |
259 ref(token, '++') | |
260 | ref(token, '--'); | |
261 | |
262 shiftOperator() => | |
263 ref(token, '<<') | |
264 | ref(token, '>') & ref(token, '>') & ref(token, '>') | |
265 | ref(token, '>') & ref(token, '>'); | |
266 | |
267 relationalOperator() => | |
268 ref(token, '>') & ref(token, '=') | |
269 | ref(token, '>') | |
270 | ref(token, '<=') | |
271 | ref(token, '<'); | |
272 | |
273 equalityOperator() => | |
274 ref(token, '==') | |
275 | ref(token, '!=') | |
276 | ref(token, '===') | |
277 | ref(token, '!=='); | |
278 | |
279 bitwiseOperator() => | |
280 ref(token, '&') | |
281 | ref(token, '^') | |
282 | ref(token, '|'); | |
283 | |
284 formalParameterList() => | |
285 ref(token, '(') & ref(namedFormalParameters).optional() & ref(token, ')'
) | |
286 | ref(token, '(') & ref(normalFormalParameter) & ref(normalFormalParameter
Tail).optional() & ref(token, ')'); | |
287 | |
288 normalFormalParameterTail() => | |
289 ref(token, ',') & ref(namedFormalParameters) | |
290 | ref(token, ',') & ref(normalFormalParameter) & ref(normalFormalParameter
Tail).optional(); | |
291 | |
292 normalFormalParameter() => | |
293 ref(functionDeclaration) | |
294 | ref(fieldFormalParameter) | |
295 | ref(simpleFormalParameter); | |
296 | |
297 simpleFormalParameter() => | |
298 ref(declaredIdentifier) | |
299 | ref(identifier); | |
300 | |
301 fieldFormalParameter() => | |
302 ref(finalVarOrType).optional() & ref(THIS) & ref(token, '.') & ref(ident
ifier); | |
303 | |
304 namedFormalParameters() => | |
305 ref(token, '[') & ref(defaultFormalParameter) & (ref(token, ',') & ref(d
efaultFormalParameter)).star() & ref(token, ']'); | |
306 | |
307 defaultFormalParameter() => | |
308 ref(normalFormalParameter) & (ref(token, '=') & ref(constantExpression))
.optional(); | |
309 | |
310 returnType() => | |
311 ref(VOID) | |
312 | ref(type); | |
313 | |
314 finalVarOrType() => | |
315 ref(FINAL) & ref(type).optional() | |
316 | ref(VAR) | |
317 | ref(type) | |
318 ; | |
319 | |
320 // We have to introduce a separate rule for 'declared' identifiers to | |
321 // allow ANTLR to decide if the first identifier we encounter after | |
322 // final is a type or an identifier. Before this change, we used the | |
323 // production 'finalVarOrType identifier' in numerous places. | |
324 declaredIdentifier() => | |
325 ref(FINAL) & ref(type).optional() & ref(identifier) | |
326 | ref(VAR) & ref(identifier) | |
327 | ref(type) & ref(identifier) | |
328 ; | |
329 | |
330 identifier() => ref(token, ref(IDENTIFIER) | |
331 | ref(ABSTRACT) | |
332 | ref(ASSERT) | |
333 | ref(CLASS) | |
334 | ref(EXTENDS) | |
335 | ref(FACTORY) | |
336 | ref(GET) | |
337 | ref(IMPLEMENTS) | |
338 | ref(IMPORT) | |
339 | ref(INTERFACE) | |
340 | ref(IS) | |
341 | ref(LIBRARY) | |
342 | ref(NATIVE) | |
343 | ref(NEGATE) | |
344 | ref(OPERATOR) | |
345 | ref(SET) | |
346 | ref(SOURCE) | |
347 | ref(STATIC) | |
348 | ref(TYPEDEF) | |
349 ); | |
350 | |
351 qualified() => | |
352 ref(identifier) & (ref(token, '.') & ref(identifier)).optional() | |
353 ; | |
354 | |
355 type() => | |
356 ref(qualified) & ref(typeArguments).optional() | |
357 ; | |
358 | |
359 typeArguments() => | |
360 ref(token, '<') & ref(typeList) & ref(token, '>') | |
361 ; | |
362 | |
363 typeList() => | |
364 ref(type) & (ref(token, ',') & ref(type)).star() | |
365 ; | |
366 | |
367 block() => | |
368 ref(token, '{') & ref(statements) & ref(token, '}') | |
369 ; | |
370 | |
371 statements() => | |
372 ref(statement).star() | |
373 ; | |
374 | |
375 statement() => | |
376 ref(label).star() & ref(nonLabelledStatement) | |
377 ; | |
378 | |
379 nonLabelledStatement() => | |
380 ref(block) | |
381 | ref(initializedVariableDeclaration) & ref(token, ';') | |
382 | ref(iterationStatement) | |
383 | ref(selectionStatement) | |
384 | ref(tryStatement) | |
385 | ref(BREAK) & ref(identifier).optional() & ref(token, ';') | |
386 | ref(CONTINUE) & ref(identifier).optional() & ref(token, ';') | |
387 | ref(RETURN) & ref(expression).optional() & ref(token, ';') | |
388 | ref(THROW) & ref(expression).optional() & ref(token, ';') | |
389 | ref(expression).optional() & ref(token, ';') | |
390 | ref(ASSERT) & ref(token, '(') & ref(conditionalExpression) & ref(token,
')') & ref(token, ';') | |
391 | ref(functionDeclaration) & ref(functionBody) | |
392 ; | |
393 | |
394 label() => | |
395 ref(identifier) & ref(token, ':') | |
396 ; | |
397 | |
398 iterationStatement() => | |
399 ref(WHILE) & ref(token, '(') & ref(expression) & ref(token, ')') & ref(s
tatement) | |
400 | ref(DO) & ref(statement) & ref(WHILE) & ref(token, '(') & ref(expression
) & ref(token, ')') & ref(token, ';') | |
401 | ref(FOR) & ref(token, '(') & ref(forLoopParts) & ref(token, ')') & ref(s
tatement) | |
402 ; | |
403 | |
404 forLoopParts() => | |
405 ref(forInitializerStatement) & ref(expression).optional() & ref(token, '
;') & ref(expressionList).optional() | |
406 | ref(declaredIdentifier) & ref(IN) & ref(expression) | |
407 | ref(identifier) & ref(IN) & ref(expression) | |
408 ; | |
409 | |
410 forInitializerStatement() => | |
411 ref(initializedVariableDeclaration) & ref(token, ';') | |
412 | ref(expression).optional() & ref(token, ';') | |
413 ; | |
414 | |
415 selectionStatement() => | |
416 ref(IF) & ref(token, '(') & ref(expression) & ref(token, ')') & ref(stat
ement) & (ref(ELSE) & ref(statement)).optional() | |
417 | ref(SWITCH) & ref(token, '(') & ref(expression) & ref(token, ')') & ref(
token, '{') & ref(switchCase).star() & ref(defaultCase).optional() & ref(token,
'}') | |
418 ; | |
419 | |
420 switchCase() => | |
421 ref(label).optional() & (ref(CASE) & ref(expression) & ref(token, ':')).
plus() & ref(statements) | |
422 ; | |
423 | |
424 defaultCase() => | |
425 ref(label).optional() & (ref(CASE) & ref(expression) & ref(token, ':')).
star() & ref(DEFAULT) & ref(token, ':') & ref(statements) | |
426 ; | |
427 | |
428 tryStatement() => | |
429 ref(TRY) & ref(block) & (ref(catchPart).plus() & ref(finallyPart).option
al() | ref(finallyPart)) | |
430 ; | |
431 | |
432 catchPart() => | |
433 ref(CATCH) & ref(token, '(') & ref(declaredIdentifier) & (ref(token, ','
) & ref(declaredIdentifier)).optional() & ref(token, ')') & ref(block) | |
434 ; | |
435 | |
436 finallyPart() => | |
437 ref(FINALLY) & ref(block) | |
438 ; | |
439 | |
440 variableDeclaration() => | |
441 ref(declaredIdentifier) & (ref(token, ',') & ref(identifier)).star() | |
442 ; | |
443 | |
444 initializedVariableDeclaration() => | |
445 ref(declaredIdentifier) & (ref(token, '=') & ref(expression)).optional()
& (ref(token, ',') & ref(initializedIdentifier)).star() | |
446 ; | |
447 | |
448 initializedIdentifierList() => | |
449 ref(initializedIdentifier) & (ref(token, ',') & ref(initializedIdentifie
r)).star() | |
450 ; | |
451 | |
452 initializedIdentifier() => | |
453 ref(identifier) & (ref(token, '=') & ref(expression)).optional() | |
454 ; | |
455 | |
456 constInitializedVariableDeclaration() => | |
457 ref(declaredIdentifier) & (ref(token, '=') & ref(constantExpression)).op
tional() & | |
458 (ref(token, ',') & ref(constInitializedIdentifier)).star() | |
459 ; | |
460 | |
461 constInitializedIdentifier() => | |
462 ref(identifier) & (ref(token, '=') & ref(constantExpression)).optional() | |
463 ; | |
464 | |
465 // The constant expression production is used to mark certain expressions | |
466 // as only being allowed to hold a compile-time constant. The grammar cannot | |
467 // express these restrictions (yet), so this will have to be enforced by a | |
468 // separate analysis phase. | |
469 constantExpression() => | |
470 ref(expression) | |
471 ; | |
472 | |
473 expression() => | |
474 ref(assignableExpression) & ref(assignmentOperator) & ref(expression) | |
475 | ref(conditionalExpression) | |
476 ; | |
477 | |
478 expressionList() => | |
479 ref(expression) & (ref(token, ',') & ref(expression)).star() | |
480 ; | |
481 | |
482 arguments() => | |
483 ref(token, '(') & ref(argumentList).optional() & ref(token, ')') | |
484 ; | |
485 | |
486 argumentList() => | |
487 ref(namedArgument) & (ref(token, ',') & ref(namedArgument)).star() | |
488 | ref(expressionList) & (ref(token, ',') & ref(namedArgument)).star() | |
489 ; | |
490 | |
491 namedArgument() => | |
492 ref(label) & ref(expression) | |
493 ; | |
494 | |
495 assignableExpression() => | |
496 ref(primary) & (ref(arguments).star() & ref(assignableSelector)).plus() | |
497 | ref(SUPER) & ref(assignableSelector) | |
498 | ref(identifier) | |
499 ; | |
500 | |
501 conditionalExpression() => | |
502 ref(logicalOrExpression) & (ref(token, '?') & ref(expression) & ref(toke
n, ':') & ref(expression)).optional() | |
503 ; | |
504 | |
505 logicalOrExpression() => | |
506 ref(logicalAndExpression) & (ref(token, '||') & ref(logicalAndExpression
)).star() | |
507 ; | |
508 | |
509 logicalAndExpression() => | |
510 ref(bitwiseOrExpression) & (ref(token, '&&') & ref(bitwiseOrExpression))
.star() | |
511 ; | |
512 | |
513 bitwiseOrExpression() => | |
514 ref(bitwiseXorExpression) & (ref(token, '|') & ref(bitwiseXorExpression)
).star() | |
515 | ref(SUPER) & (ref(token, '|') & ref(bitwiseXorExpression)).plus() | |
516 ; | |
517 | |
518 bitwiseXorExpression() => | |
519 ref(bitwiseAndExpression) & (ref(token, '^') & ref(bitwiseAndExpression)
).star() | |
520 | ref(SUPER) & (ref(token, '^') & ref(bitwiseAndExpression)).plus() | |
521 ; | |
522 | |
523 bitwiseAndExpression() => | |
524 ref(equalityExpression) & (ref(token, '&') & ref(equalityExpression)).st
ar() | |
525 | ref(SUPER) & (ref(token, '&') & ref(equalityExpression)).plus() | |
526 ; | |
527 | |
528 equalityExpression() => | |
529 ref(relationalExpression) & (ref(equalityOperator) & ref(relationalExpre
ssion)).optional() | |
530 | ref(SUPER) & ref(equalityOperator) & ref(relationalExpression) | |
531 ; | |
532 | |
533 relationalExpression() => | |
534 ref(shiftExpression) & (ref(isOperator) & ref(type) | ref(relationalOper
ator) & ref(shiftExpression)).optional() | |
535 | ref(SUPER) & ref(relationalOperator) & ref(shiftExpression) | |
536 ; | |
537 | |
538 isOperator() => | |
539 ref(IS) & ref(token, '!').optional() | |
540 ; | |
541 | |
542 shiftExpression() => | |
543 ref(additiveExpression) & (ref(shiftOperator) & ref(additiveExpression))
.star() | |
544 | ref(SUPER) & (ref(shiftOperator) & ref(additiveExpression)).plus() | |
545 ; | |
546 | |
547 additiveExpression() => | |
548 ref(multiplicativeExpression) & (ref(additiveOperator) & ref(multiplicat
iveExpression)).star() | |
549 | ref(SUPER) & (ref(additiveOperator) & ref(multiplicativeExpression)).plu
s() | |
550 ; | |
551 | |
552 multiplicativeExpression() => | |
553 ref(unaryExpression) & (ref(multiplicativeOperator) & ref(unaryExpressio
n)).star() | |
554 | ref(SUPER) & (ref(multiplicativeOperator) & ref(unaryExpression)).plus() | |
555 ; | |
556 | |
557 unaryExpression() => | |
558 ref(postfixExpression) | |
559 | ref(prefixOperator) & ref(unaryExpression) | |
560 | ref(negateOperator) & ref(SUPER) | |
561 | ref(token, '-') & ref(SUPER) | |
562 | ref(incrementOperator) & ref(assignableExpression) | |
563 ; | |
564 | |
565 postfixExpression() => | |
566 ref(assignableExpression) & ref(postfixOperator) | |
567 | ref(primary) & ref(selector).star() | |
568 ; | |
569 | |
570 selector() => | |
571 ref(assignableSelector) | |
572 | ref(arguments) | |
573 ; | |
574 | |
575 assignableSelector() => | |
576 ref(token, '[') & ref(expression) & ref(token, ']') | |
577 | ref(token, '.') & ref(identifier) | |
578 ; | |
579 | |
580 primary() => | |
581 ref(primaryNoFE) | |
582 | ref(primaryFE) | |
583 ; | |
584 | |
585 primaryFE() => | |
586 ref(functionExpression) | |
587 | ref(primaryNoFE) | |
588 ; | |
589 | |
590 primaryNoFE() => | |
591 ref(THIS) | |
592 | ref(SUPER) & ref(assignableSelector) | |
593 | ref(literal) | |
594 | ref(identifier) | |
595 | ref(CONST).optional() & ref(typeArguments).optional() & ref(compoundLite
ral) | |
596 | (ref(NEW) | ref(CONST)) & ref(type) & (ref(token, '.') & ref(identifier)
).optional() & ref(arguments) | |
597 | ref(expressionInParentheses) | |
598 ; | |
599 | |
600 expressionInParentheses() => | |
601 ref(token, '(') & ref(expression) & ref(token, ')') | |
602 ; | |
603 | |
604 literal() => ref(token, | |
605 ref(NULL) | |
606 | ref(TRUE) | |
607 | ref(FALSE) | |
608 | ref(HEX_NUMBER) | |
609 | ref(NUMBER) | |
610 | ref(STRING)) | |
611 ; | |
612 | |
613 compoundLiteral() => | |
614 ref(listLiteral) | |
615 | ref(mapLiteral) | |
616 ; | |
617 | |
618 listLiteral() => | |
619 ref(token, '[') & (ref(expressionList) & ref(token, ',').optional()).opt
ional() & ref(token, ']') | |
620 ; | |
621 | |
622 mapLiteral() => | |
623 ref(token, '{') & (ref(mapLiteralEntry) & (ref(token, ',') & ref(mapLite
ralEntry)).star() & ref(token, ',').optional()).optional() & ref(token, '}') | |
624 ; | |
625 | |
626 mapLiteralEntry() => | |
627 ref(token, STRING) & ref(token, ':') & ref(expression) | |
628 ; | |
629 | |
630 functionExpression() => | |
631 (ref(returnType).optional() & ref(identifier)).optional() & ref(formalPa
rameterList) & ref(functionExpressionBody) | |
632 ; | |
633 | |
634 functionDeclaration() => | |
635 ref(returnType).optional() & ref(identifier) & ref(formalParameterList) | |
636 ; | |
637 | |
638 functionPrefix() => | |
639 ref(returnType).optional() & ref(identifier) | |
640 ; | |
641 | |
642 functionBody() => | |
643 ref(token, '=>') & ref(expression) & ref(token, ';') | |
644 | ref(block) | |
645 ; | |
646 | |
647 functionExpressionBody() => | |
648 ref(token, '=>') & ref(expression) | |
649 | ref(block) | |
650 ; | |
651 | |
652 // ----------------------------------------------------------------- | |
653 // Library files. | |
654 // ----------------------------------------------------------------- | |
655 libraryUnit() => | |
656 ref(libraryDefinition).end() | |
657 ; | |
658 | |
659 libraryDefinition() => | |
660 ref(LIBRARY) & ref(token, '{') & ref(libraryBody) & ref(token, '}') | |
661 ; | |
662 | |
663 libraryBody() => | |
664 ref(libraryImport).optional() & ref(librarySource).optional() | |
665 ; | |
666 | |
667 libraryImport() => | |
668 ref(IMPORT) & ref(token, '=') & ref(token, '[') & ref(importReferences).
optional() & ref(token, ']') | |
669 ; | |
670 | |
671 importReferences() => | |
672 ref(importReference) & (ref(token, ',') & ref(importReference)).star() &
ref(token, ',').optional() | |
673 ; | |
674 | |
675 importReference() => | |
676 (ref(token, IDENTIFIER) & ref(token, ':')).optional() & ref(token, STRIN
G) | |
677 ; | |
678 | |
679 librarySource() => | |
680 ref(SOURCE) & ref(token, '=') & ref(token, '[') & ref(sourceUrls).option
al() & ref(token, ']') | |
681 ; | |
682 | |
683 sourceUrls() => | |
684 ref(token, STRING) & (ref(token, ',') & ref(token, STRING)).star() & ref
(token, ',').optional() | |
685 ; | |
686 | |
687 | |
688 // ----------------------------------------------------------------- | |
689 // Lexical tokens. | |
690 // ----------------------------------------------------------------- | |
691 IDENTIFIER_NO_DOLLAR() => | |
692 ref(IDENTIFIER_START_NO_DOLLAR) & ref(IDENTIFIER_PART_NO_DOLLAR).star() | |
693 ; | |
694 | |
695 IDENTIFIER() => | |
696 ref(IDENTIFIER_START) & ref(IDENTIFIER_PART).star() | |
697 ; | |
698 | |
699 HEX_NUMBER() => | |
700 string('0x') & ref(HEX_DIGIT).plus() | |
701 | string('0X') & ref(HEX_DIGIT).plus() | |
702 ; | |
703 | |
704 NUMBER() => | |
705 ref(DIGIT).plus() & ref(NUMBER_OPT_FRACTIONAL_PART) & ref(EXPONENT).opti
onal() & ref(NUMBER_OPT_ILLEGAL_END) | |
706 | char('.') & ref(DIGIT).plus() & ref(EXPONENT).optional() & ref(NUMBER_OP
T_ILLEGAL_END) | |
707 ; | |
708 | |
709 NUMBER_OPT_FRACTIONAL_PART() => | |
710 char('.') & ref(DIGIT).plus() | |
711 | epsilon() | |
712 ; | |
713 | |
714 NUMBER_OPT_ILLEGAL_END() => epsilon(); | |
715 // ref(IDENTIFIER_START).end() | |
716 // | epsilon() | |
717 // ; | |
718 | |
719 HEX_DIGIT() => pattern('0-9a-fA-F'); | |
720 | |
721 IDENTIFIER_START() => ref(IDENTIFIER_START_NO_DOLLAR) | char('\$'); | |
722 | |
723 IDENTIFIER_START_NO_DOLLAR() => ref(LETTER) | char('_'); | |
724 | |
725 IDENTIFIER_PART_NO_DOLLAR() => ref(IDENTIFIER_START_NO_DOLLAR) | ref(DIGIT); | |
726 | |
727 IDENTIFIER_PART() => ref(IDENTIFIER_START) | ref(DIGIT); | |
728 | |
729 LETTER() => letter(); | |
730 | |
731 DIGIT() => digit(); | |
732 | |
733 EXPONENT() => pattern('eE') & pattern('+-').optional() & ref(DIGIT).plus(); | |
734 | |
735 STRING() => | |
736 char('@').optional() & ref(MULTI_LINE_STRING) | |
737 | ref(SINGLE_LINE_STRING) | |
738 ; | |
739 | |
740 MULTI_LINE_STRING() => | |
741 string('"""') & any().starLazy(string('"""')) & string('"""') | |
742 | string("'''") & any().starLazy(string("'''")) & string("'''") | |
743 ; | |
744 | |
745 SINGLE_LINE_STRING() => | |
746 char('"') & ref(STRING_CONTENT_DQ).star() & char('"') | |
747 | char("'") & ref(STRING_CONTENT_SQ).star() & char("'") | |
748 | string('@"') & pattern('^"\n\r').star() & char('"') | |
749 | string("@'") & pattern("^'\n\r").star() & char("'") | |
750 ; | |
751 | |
752 STRING_CONTENT_DQ() => | |
753 pattern('^\\"\n\r') | |
754 | char('\\') & pattern('\n\r') | |
755 ; | |
756 | |
757 STRING_CONTENT_SQ() => | |
758 pattern("^\\'\n\r") | |
759 | char('\\') & pattern('\n\r') | |
760 ; | |
761 | |
762 NEWLINE() => pattern('\n\r'); | |
763 | |
764 HASHBANG() => string('#!') & pattern('^\n\r').star() & ref(NEWLINE).optional()
; | |
765 | |
766 | |
767 // ----------------------------------------------------------------- | |
768 // Whitespace and comments. | |
769 // ----------------------------------------------------------------- | |
770 HIDDEN() => ref(HIDDEN_STUFF).plus(); | |
771 | |
772 HIDDEN_STUFF() => ref(WHITESPACE) | |
773 | ref(SINGLE_LINE_COMMENT) | |
774 | ref(MULTI_LINE_COMMENT) | |
775 ; | |
776 | |
777 WHITESPACE() => whitespace(); | |
778 | |
779 SINGLE_LINE_COMMENT() => string('//') | |
780 & ref(NEWLINE).neg().star() | |
781 & ref(NEWLINE).optional() | |
782 ; | |
783 | |
784 MULTI_LINE_COMMENT() => string('/*') | |
785 & (ref(MULTI_LINE_COMMENT) | string('*/').neg()).star() & string('*/') | |
786 ; | |
787 | |
788 } | |
OLD | NEW |