Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(26)

Side by Side Diff: dart/language/grammar/Dart.g

Issue 10917035: Remove language directory. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | dart/language/grammar/Makefile » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 grammar Dart;
6
7 options {
8 backtrack = true;
9 memoize = true;
10 output = AST;
11 }
12
13
14 // -----------------------------------------------------------------
15 // Keyword definitions.
16 // -----------------------------------------------------------------
17 tokens {
18 BREAK = 'break';
19 CASE = 'case';
20 CATCH = 'catch';
21 CONST = 'const';
22 CONTINUE = 'continue';
23 DEFAULT = 'default';
24 DO = 'do';
25 ELSE = 'else';
26 FALSE = 'false';
27 FINAL = 'final';
28 FINALLY = 'finally';
29 FOR = 'for';
30 IF = 'if';
31 IN = 'in';
32 NEW = 'new';
33 NULL = 'null';
34 RETURN = 'return';
35 SUPER = 'super';
36 SWITCH = 'switch';
37 THIS = 'this';
38 THROW = 'throw';
39 TRUE = 'true';
40 TRY = 'try';
41 VAR = 'var';
42 VOID = 'void';
43 WHILE = 'while';
44
45 // Pseudo-keywords that should also be valid identifiers.
46 ABSTRACT = 'abstract';
47 ASSERT = 'assert';
48 CLASS = 'class';
49 EXTENDS = 'extends';
50 FACTORY = 'factory';
51 GET = 'get';
52 IMPLEMENTS = 'implements';
53 IMPORT = 'import';
54 INTERFACE = 'interface';
55 IS = 'is';
56 LIBRARY = 'library';
57 NATIVE = 'native';
58 NEGATE = 'negate';
59 OPERATOR = 'operator';
60 SET = 'set';
61 SOURCE = 'source';
62 STATIC = 'static';
63 TYPEDEF = 'typedef';
64 }
65
66 @header {
67 package com.google.dart.antlr;
68 }
69
70 @lexer::header {
71 package com.google.dart.antlr;
72 }
73
74 @lexer::members {
75 public boolean hasErrors = false;
76
77 @Override
78 public String getErrorHeader(RecognitionException exception) {
79 String sourceName = input.getSourceName();
80 if (sourceName == null) {
81 sourceName = "<unknown source>";
82 }
83 return sourceName + ":" + exception.line + ":"
84 + (exception.charPositionInLine + 1) + ":";
85 }
86
87 @Override
88 public void reportError(RecognitionException exception) {
89 hasErrors = true;
90 super.reportError(exception);
91 }
92
93 // Disable single token insertion and deletion, see:
94 // http://www.antlr.org/wiki/display/ANTLR3/Error+reporting+and+recovery
95 @Override
96 protected Object recoverFromMismatchedToken(IntStream input,
97 int ttype,
98 BitSet follow)
99 throws RecognitionException
100 {
101 throw new MismatchedTokenException(ttype, input);
102 }
103
104 private void error(String message) {
105 hasErrors = true;
106 int line = state.tokenStartLine;
107 int column = state.tokenStartCharPositionInLine;
108 String sourceName = input.getSourceName();
109 if (sourceName == null) {
110 sourceName = "<unknown source>";
111 }
112 emitErrorMessage(sourceName + ":" + line + ":" + (column + 1) + ": "
113 + message);
114 }
115 }
116
117 @members {
118 public boolean hasErrors = false;
119
120 private boolean parseFunctionExpressions = true;
121 private boolean setParseFunctionExpressions(boolean value) {
122 boolean old = parseFunctionExpressions;
123 parseFunctionExpressions = value;
124 return old;
125 }
126
127 @Override
128 public String getErrorHeader(RecognitionException exception) {
129 String sourceName = input.getSourceName();
130 if (sourceName == null) {
131 sourceName = "<unknown source>";
132 }
133 return sourceName + ":" + exception.line + ":"
134 + (exception.charPositionInLine + 1) + ":";
135 }
136
137 @Override
138 public void reportError(RecognitionException exception) {
139 hasErrors = true;
140 super.reportError(exception);
141 }
142
143 // What to do with this method? Currently, error recovery
144 // is brain-dead and we often get too many error messages just from
145 // one error. This method represents one extreme solution to that
146 // problem.
147 // @Override
148 // public void recover(IntStream input, RecognitionException re) {
149 // // Consume all input so we only see one parser error. This trick
150 // // does not work for the lexer.
151 // consumeUntil(input, Token.EOF);
152 // }
153
154 // Disable single token insertion and deletion, see:
155 // http://www.antlr.org/wiki/display/ANTLR3/Error+reporting+and+recovery
156 @Override
157 protected Object recoverFromMismatchedToken(IntStream input,
158 int ttype,
159 BitSet follow)
160 throws RecognitionException
161 {
162 throw new MismatchedTokenException(ttype, input);
163 }
164
165 private Token firstHiddenToken() {
166 Token token = input.LT(1); // The next token.
167 int index = token.getTokenIndex() - 1; // The previous token.
168 if (index >= 0) {
169 token = input.get(index);
170 }
171 // Skip whitespace, comments, etc.
172 while ((index > 0) && (token.getChannel() == Token.HIDDEN_CHANNEL)) {
173 token = input.get(--index);
174 }
175 return input.get(index + 1);
176 }
177
178 private void emitMessage(Token token, String message) {
179 int line = token.getLine();
180 int column = token.getCharPositionInLine();
181 String sourceName = input.getSourceName();
182 if (sourceName == null) {
183 sourceName = "<unknown source>";
184 }
185 emitErrorMessage(sourceName + ":" + line + ":" + (column + 1) + ": "
186 + message);
187 }
188
189 private void warning(Token token, String message) {
190 emitMessage(token, "warning: " + message);
191 }
192
193 private void legacy(Token token, String message) {
194 warning(token, message);
195 }
196
197 private void semicolon() {
198 error(null, "missing ';'");
199 }
200
201 private void error(Token token, String message) {
202 if (token == null) {
203 token = firstHiddenToken();
204 }
205 hasErrors = true;
206 emitMessage(token, message);
207 }
208 }
209
210 // -----------------------------------------------------------------
211 // Grammar productions.
212 // -----------------------------------------------------------------
213 compilationUnit
214 : HASHBANG? directive* topLevelDefinition* EOF
215 ;
216
217 directive
218 : '#' identifier arguments ';'
219 ;
220
221 topLevelDefinition
222 : (CLASS)=> classDefinition
223 | (INTERFACE)=> interfaceDefinition
224 | (TYPEDEF)=> functionTypeAlias
225 | functionDeclaration functionBodyOrNative
226 | returnType? getOrSet identifier formalParameterList functionBodyOrNative
227 | FINAL type? staticFinalDeclarationList ';'
228 | constInitializedVariableDeclaration ';'
229 ;
230
231 classDefinition
232 : CLASS identifier typeParameters? superclass? interfaces?
233 '{' classMemberDefinition* '}'
234 | CLASS identifier typeParameters? interfaces? NATIVE STRING
235 '{' classMemberDefinition* '}'
236 { warning($start, "DartC: native can only be used in platform code"); }
237 ;
238
239 typeParameter
240 : identifier (EXTENDS type)?
241 ;
242
243 typeParameters
244 : '<' typeParameter (',' typeParameter)* '>'
245 ;
246
247 superclass
248 : EXTENDS type
249 ;
250
251 interfaces
252 : IMPLEMENTS typeList
253 ;
254
255 superinterfaces
256 : EXTENDS typeList
257 ;
258
259 // This rule is organized in a way that may not be most readable, but
260 // gives the best error messages.
261 classMemberDefinition
262 : declaration ';'
263 | constructorDeclaration ';'
264 | methodDeclaration functionBodyOrNative
265 | CONST factoryConstructorDeclaration functionNative
266 ;
267
268 functionBodyOrNative
269 : NATIVE functionBody
270 { warning($start, "native function with body only works on DartC"); }
271 | functionNative
272 | functionBody
273 ;
274
275 functionNative
276 : NATIVE STRING? ';'
277 { warning($start, "native can only be used in platform code"); }
278 ;
279
280 // A method, operator, or constructor (which all should be followed by
281 // a block of code).
282 methodDeclaration
283 : factoryConstructorDeclaration
284 | STATIC functionDeclaration
285 | specialSignatureDefinition
286 | functionDeclaration initializers?
287 | namedConstructorDeclaration initializers?
288 ;
289
290 // An abstract method/operator, a field, or const constructor (which
291 // all should be followed by a semicolon).
292 declaration
293 : constantConstructorDeclaration (redirection | initializers)?
294 | functionDeclaration redirection
295 | namedConstructorDeclaration redirection
296 | ABSTRACT specialSignatureDefinition
297 | ABSTRACT functionDeclaration
298 | STATIC FINAL type? staticFinalDeclarationList
299 | STATIC? constInitializedVariableDeclaration
300 ;
301
302 initializers
303 : ':' superCallOrFieldInitializer (',' superCallOrFieldInitializer)*
304 ;
305
306 redirection
307 : ':' THIS ('.' identifier)? arguments
308 ;
309
310 fieldInitializer
311 @init { boolean old = setParseFunctionExpressions(false); }
312 : (THIS '.')? identifier '=' conditionalExpression
313 ;
314 finally { setParseFunctionExpressions(old); }
315
316 superCallOrFieldInitializer
317 : SUPER arguments
318 | SUPER '.' identifier arguments
319 | fieldInitializer
320 ;
321
322 staticFinalDeclarationList
323 : staticFinalDeclaration (',' staticFinalDeclaration)*
324 ;
325
326 staticFinalDeclaration
327 : identifier '=' constantExpression
328 ;
329
330 interfaceDefinition
331 : INTERFACE identifier typeParameters? superinterfaces?
332 factorySpecification? '{' (interfaceMemberDefinition)* '}'
333 ;
334
335 factorySpecification
336 : FACTORY type
337 ;
338
339 functionTypeAlias
340 : TYPEDEF functionPrefix typeParameters? formalParameterList ';'
341 ;
342
343 interfaceMemberDefinition
344 : STATIC FINAL type? initializedIdentifierList ';'
345 | functionDeclaration ';'
346 | constantConstructorDeclaration ';'
347 | namedConstructorDeclaration ';'
348 | specialSignatureDefinition ';'
349 | variableDeclaration ';'
350 ;
351
352 factoryConstructorDeclaration
353 : FACTORY qualified typeParameters? ('.' identifier)? formalParameterList
354 ;
355
356 namedConstructorDeclaration
357 : identifier '.' identifier formalParameterList
358 ;
359
360 constructorDeclaration
361 : identifier formalParameterList (redirection | initializers)?
362 | namedConstructorDeclaration (redirection | initializers)?
363 ;
364
365 constantConstructorDeclaration
366 : CONST qualified formalParameterList
367 ;
368
369 specialSignatureDefinition
370 : STATIC? returnType? getOrSet identifier formalParameterList
371 | returnType? OPERATOR userDefinableOperator formalParameterList
372 ;
373
374 getOrSet
375 : GET
376 | SET
377 ;
378
379 userDefinableOperator
380 : multiplicativeOperator
381 | additiveOperator
382 | shiftOperator
383 | relationalOperator
384 | bitwiseOperator
385 | '==' // Disallow negative and === equality checks.
386 | '~' // Disallow ! operator.
387 | NEGATE
388 | '[' ']' { "[]".equals($text) }?
389 | '[' ']' '=' { "[]=".equals($text) }?
390 ;
391
392 prefixOperator
393 : additiveOperator
394 | negateOperator
395 ;
396
397 postfixOperator
398 : incrementOperator
399 ;
400
401 negateOperator
402 : '!'
403 | '~'
404 ;
405
406 multiplicativeOperator
407 : '*'
408 | '/'
409 | '%'
410 | '~/'
411 ;
412
413 assignmentOperator
414 : '='
415 | '*='
416 | '/='
417 | '~/='
418 | '%='
419 | '+='
420 | '-='
421 | '<<='
422 | '>' '>' '>' '=' { ">>>=".equals($text) }?
423 | '>' '>' '=' { ">>=".equals($text) }?
424 | '&='
425 | '^='
426 | '|='
427 ;
428
429 additiveOperator
430 : '+'
431 | '-'
432 ;
433
434 incrementOperator
435 : '++'
436 | '--'
437 ;
438
439 shiftOperator
440 : '<<'
441 | '>' '>' '>' { ">>>".equals($text) }?
442 | '>' '>' { ">>".equals($text) }?
443 ;
444
445 relationalOperator
446 : '>' '=' { ">=".equals($text) }?
447 | '>'
448 | '<='
449 | '<'
450 ;
451
452 equalityOperator
453 : '=='
454 | '!='
455 | '==='
456 | '!=='
457 ;
458
459 bitwiseOperator
460 : '&'
461 | '^'
462 | '|'
463 ;
464
465 formalParameterList
466 : '(' namedFormalParameters? ')'
467 | '(' normalFormalParameter normalFormalParameterTail? ')'
468 ;
469
470 normalFormalParameterTail
471 : ',' namedFormalParameters
472 | ',' normalFormalParameter normalFormalParameterTail?
473 ;
474
475 normalFormalParameter
476 : functionDeclaration
477 | fieldFormalParameter
478 | simpleFormalParameter
479 ;
480
481 simpleFormalParameter
482 : declaredIdentifier
483 | identifier
484 ;
485
486 fieldFormalParameter
487 : finalVarOrType? THIS '.' identifier
488 ;
489
490 namedFormalParameters
491 : '[' defaultFormalParameter (',' defaultFormalParameter)* ']'
492 ;
493
494 defaultFormalParameter
495 : normalFormalParameter ('=' constantExpression)?
496 ;
497
498 returnType
499 : VOID
500 | type
501 ;
502
503 finalVarOrType
504 : FINAL type?
505 | VAR
506 | type
507 ;
508
509 // We have to introduce a separate rule for 'declared' identifiers to
510 // allow ANTLR to decide if the first identifier we encounter after
511 // final is a type or an identifier. Before this change, we used the
512 // production 'finalVarOrType identifier' in numerous places.
513 declaredIdentifier
514 : FINAL type? identifier
515 | VAR identifier
516 | type identifier
517 ;
518
519 identifier
520 : IDENTIFIER_NO_DOLLAR
521 | IDENTIFIER
522 | ABSTRACT
523 | ASSERT
524 | CLASS
525 | EXTENDS
526 | FACTORY
527 | GET
528 | IMPLEMENTS
529 | IMPORT
530 | INTERFACE
531 | IS
532 | LIBRARY
533 | NATIVE
534 | NEGATE
535 | OPERATOR
536 | SET
537 | SOURCE
538 | STATIC
539 | TYPEDEF
540 ;
541
542 qualified
543 : identifier ('.' identifier)?
544 ;
545
546 type
547 : qualified typeArguments?
548 ;
549
550 typeArguments
551 : '<' typeList '>'
552 ;
553
554 typeList
555 : type (',' type)*
556 ;
557
558 block
559 : '{' statements '}'
560 ;
561
562 statements
563 : statement*
564 ;
565
566 statement
567 : label* nonLabelledStatement
568 ;
569
570 nonLabelledStatement
571 : ('{')=> block // Guard to break tie with map literal.
572 | initializedVariableDeclaration ';'
573 | iterationStatement
574 | selectionStatement
575 | tryStatement
576 | BREAK identifier? ';'
577 | CONTINUE identifier? ';'
578 | RETURN expression? ';'
579 | THROW expression? ';'
580 | expression? ';'
581 | ASSERT '(' conditionalExpression ')' ';'
582 | functionDeclaration functionBody
583 ;
584
585 label
586 : identifier ':'
587 ;
588
589 iterationStatement
590 : WHILE '(' expression ')' statement
591 | DO statement WHILE '(' expression ')' ';'
592 | FOR '(' forLoopParts ')' statement
593 ;
594
595 forLoopParts
596 : forInitializerStatement expression? ';' expressionList?
597 | declaredIdentifier IN expression
598 | identifier IN expression
599 ;
600
601 forInitializerStatement
602 : initializedVariableDeclaration ';'
603 | expression? ';'
604 ;
605
606 selectionStatement
607 : IF '(' expression ')' statement ((ELSE)=> ELSE statement)?
608 | SWITCH '(' expression ')' '{' switchCase* defaultCase? '}'
609 ;
610
611 switchCase
612 : label? (CASE expression ':')+ statements
613 ;
614
615 defaultCase
616 : label? (CASE expression ':')* DEFAULT ':' statements
617 ;
618
619 tryStatement
620 : TRY block (catchPart+ finallyPart? | finallyPart)
621 ;
622
623 catchPart
624 : CATCH '(' declaredIdentifier (',' declaredIdentifier)? ')' block
625 ;
626
627 finallyPart
628 : FINALLY block
629 ;
630
631 variableDeclaration
632 : declaredIdentifier (',' identifier)*
633 ;
634
635 initializedVariableDeclaration
636 : declaredIdentifier ('=' expression)? (',' initializedIdentifier)*
637 ;
638
639 initializedIdentifierList
640 : initializedIdentifier (',' initializedIdentifier)*
641 ;
642
643 initializedIdentifier
644 : identifier ('=' expression)?
645 ;
646
647 constInitializedVariableDeclaration
648 : declaredIdentifier ('=' constantExpression)?
649 (',' constInitializedIdentifier)*
650 ;
651
652 constInitializedIdentifier
653 : identifier ('=' constantExpression)?
654 ;
655
656 // The constant expression production is used to mark certain expressions
657 // as only being allowed to hold a compile-time constant. The grammar cannot
658 // express these restrictions (yet), so this will have to be enforced by a
659 // separate analysis phase.
660 constantExpression
661 : expression
662 ;
663
664 expression
665 : assignableExpression assignmentOperator expression
666 | conditionalExpression
667 ;
668
669 expressionList
670 : expression (',' expression)*
671 ;
672
673 arguments
674 @init { boolean old = setParseFunctionExpressions(true); }
675 : '(' argumentList? ')'
676 ;
677 finally { setParseFunctionExpressions(old); }
678
679 argumentList
680 : namedArgument (',' namedArgument)*
681 | expressionList (',' namedArgument)*
682 ;
683
684 namedArgument
685 : label expression
686 ;
687
688 assignableExpression
689 : primary (arguments* assignableSelector)+
690 | SUPER assignableSelector
691 | identifier
692 ;
693
694 conditionalExpression
695 : logicalOrExpression ('?' expression ':' expression)?
696 ;
697
698 logicalOrExpression
699 : logicalAndExpression ('||' logicalAndExpression)*
700 ;
701
702 logicalAndExpression
703 : bitwiseOrExpression ('&&' bitwiseOrExpression)*
704 ;
705
706 bitwiseOrExpression
707 : bitwiseXorExpression ('|' bitwiseXorExpression)*
708 | SUPER ('|' bitwiseXorExpression)+
709 ;
710
711 bitwiseXorExpression
712 : bitwiseAndExpression ('^' bitwiseAndExpression)*
713 | SUPER ('^' bitwiseAndExpression)+
714 ;
715
716 bitwiseAndExpression
717 : equalityExpression ('&' equalityExpression)*
718 | SUPER ('&' equalityExpression)+
719 ;
720
721 equalityExpression
722 : relationalExpression (equalityOperator relationalExpression)?
723 | SUPER equalityOperator relationalExpression
724 ;
725
726 relationalExpression
727 : shiftExpression (isOperator type | relationalOperator shiftExpression)?
728 | SUPER relationalOperator shiftExpression
729 ;
730
731 isOperator
732 : IS '!'?
733 ;
734
735 shiftExpression
736 : additiveExpression (shiftOperator additiveExpression)*
737 | SUPER (shiftOperator additiveExpression)+
738 ;
739
740 additiveExpression
741 : multiplicativeExpression (additiveOperator multiplicativeExpression)*
742 | SUPER (additiveOperator multiplicativeExpression)+
743 ;
744
745 multiplicativeExpression
746 : unaryExpression (multiplicativeOperator unaryExpression)*
747 | SUPER (multiplicativeOperator unaryExpression)+
748 ;
749
750 unaryExpression
751 : postfixExpression
752 | prefixOperator unaryExpression
753 | negateOperator SUPER
754 | '-' SUPER // Invokes the NEGATE operator.
755 | incrementOperator assignableExpression
756 ;
757
758 postfixExpression
759 : assignableExpression postfixOperator
760 | primary selector*
761 ;
762
763 selector
764 : assignableSelector
765 | arguments
766 ;
767
768 assignableSelector
769 @init { boolean old = setParseFunctionExpressions(true); }
770 : '[' expression ']'
771 | '.' identifier
772 ;
773 finally { setParseFunctionExpressions(old); }
774
775 primary
776 : {!parseFunctionExpressions}?=> primaryNoFE
777 | primaryFE
778 ;
779
780 primaryFE
781 : functionExpression
782 | primaryNoFE
783 ;
784
785 primaryNoFE
786 : THIS
787 | SUPER assignableSelector
788 | literal
789 | identifier
790 | CONST? typeArguments? compoundLiteral
791 | (NEW | CONST) type ('.' identifier)? arguments
792 | expressionInParentheses
793 ;
794
795 expressionInParentheses
796 @init { boolean old = setParseFunctionExpressions(true); }
797 :'(' expression ')'
798 ;
799 finally { setParseFunctionExpressions(old); }
800
801 literal
802 : NULL
803 | TRUE
804 | FALSE
805 | HEX_NUMBER
806 | NUMBER
807 | STRING
808 ;
809
810 compoundLiteral
811 @init { boolean old = setParseFunctionExpressions(true); }
812 : listLiteral
813 | mapLiteral
814 ;
815 finally { setParseFunctionExpressions(old); }
816
817 // The list literal syntax doesn't allow elided elements, unlike
818 // in ECMAScript. We do allow a trailing comma.
819 listLiteral
820 : '[' (expressionList ','?)? ']'
821 ;
822
823 mapLiteral
824 : '{' (mapLiteralEntry (',' mapLiteralEntry)* ','?)? '}'
825 ;
826
827 mapLiteralEntry
828 : STRING ':' expression
829 ;
830
831 functionExpression
832 : (returnType? identifier)? formalParameterList functionExpressionBody
833 ;
834
835 functionDeclaration
836 : returnType? identifier formalParameterList
837 ;
838
839 functionPrefix
840 : returnType? identifier
841 ;
842
843 functionBody
844 : '=>' expression ';'
845 | block
846 ;
847
848 functionExpressionBody
849 : '=>' expression
850 | block
851 ;
852
853 // -----------------------------------------------------------------
854 // Library files.
855 // -----------------------------------------------------------------
856 libraryUnit
857 : libraryDefinition EOF
858 ;
859
860 libraryDefinition
861 : LIBRARY '{' libraryBody '}'
862 ;
863
864 libraryBody
865 : libraryImport? librarySource?
866 ;
867
868 libraryImport
869 : IMPORT '=' '[' importReferences? ']'
870 ;
871
872 importReferences
873 : importReference (',' importReference)* ','?
874 ;
875
876 importReference
877 : (IDENTIFIER ':')? STRING
878 ;
879
880 librarySource
881 : SOURCE '=' '[' sourceUrls? ']'
882 ;
883
884 sourceUrls
885 : STRING (',' STRING)* ','?
886 ;
887
888
889 // -----------------------------------------------------------------
890 // Lexical tokens.
891 // -----------------------------------------------------------------
892 IDENTIFIER_NO_DOLLAR
893 : IDENTIFIER_START_NO_DOLLAR IDENTIFIER_PART_NO_DOLLAR*
894 ;
895
896 IDENTIFIER
897 : IDENTIFIER_START IDENTIFIER_PART*
898 ;
899
900 HEX_NUMBER
901 : '0x' HEX_DIGIT+
902 | '0X' HEX_DIGIT+
903 ;
904
905 NUMBER
906 : DIGIT+ NUMBER_OPT_FRACTIONAL_PART EXPONENT? NUMBER_OPT_ILLEGAL_END
907 | '.' DIGIT+ EXPONENT? NUMBER_OPT_ILLEGAL_END
908 ;
909
910 fragment NUMBER_OPT_FRACTIONAL_PART
911 : ('.' DIGIT)=> ('.' DIGIT+)
912 | // Empty fractional part.
913 ;
914
915 fragment NUMBER_OPT_ILLEGAL_END
916 : (IDENTIFIER_START)=> { error("numbers cannot contain identifiers"); }
917 | // Empty illegal end (good!).
918 ;
919
920 fragment HEX_DIGIT
921 : 'a'..'f'
922 | 'A'..'F'
923 | DIGIT
924 ;
925
926 fragment IDENTIFIER_START
927 : IDENTIFIER_START_NO_DOLLAR
928 | '$'
929 ;
930
931 fragment IDENTIFIER_START_NO_DOLLAR
932 : LETTER
933 | '_'
934 ;
935
936 fragment IDENTIFIER_PART_NO_DOLLAR
937 : IDENTIFIER_START_NO_DOLLAR
938 | DIGIT
939 ;
940
941 fragment IDENTIFIER_PART
942 : IDENTIFIER_START
943 | DIGIT
944 ;
945
946 // Bug 5408613: Should be Unicode characters.
947 fragment LETTER
948 : 'a'..'z'
949 | 'A'..'Z'
950 ;
951
952 fragment DIGIT
953 : '0'..'9'
954 ;
955
956 fragment EXPONENT
957 : ('e' | 'E') ('+' | '-')? DIGIT+
958 ;
959
960 STRING
961 : '@'? MULTI_LINE_STRING
962 | SINGLE_LINE_STRING
963 ;
964
965 fragment MULTI_LINE_STRING
966 options { greedy=false; }
967 : '"""' .* '"""'
968 | '\'\'\'' .* '\'\'\''
969 ;
970
971 fragment SINGLE_LINE_STRING
972 : '"' STRING_CONTENT_DQ* '"'
973 | '\'' STRING_CONTENT_SQ* '\''
974 | '@' '\'' (~( '\'' | NEWLINE ))* '\''
975 | '@' '"' (~( '"' | NEWLINE ))* '"'
976 ;
977
978 fragment STRING_CONTENT_DQ
979 : ~( '\\' | '"' | NEWLINE )
980 | '\\' ~( NEWLINE )
981 ;
982
983 fragment STRING_CONTENT_SQ
984 : ~( '\\' | '\'' | NEWLINE )
985 | '\\' ~( NEWLINE )
986 ;
987
988 fragment NEWLINE
989 : '\n'
990 | '\r'
991 ;
992
993 BAD_STRING
994 : UNTERMINATED_STRING NEWLINE { error("unterminated string"); }
995 ;
996
997 fragment UNTERMINATED_STRING
998 : '@'? '\'' (~( '\'' | NEWLINE ))*
999 | '@'? '"' (~( '"' | NEWLINE ))*
1000 ;
1001
1002 HASHBANG
1003 : '#!' ~(NEWLINE)* (NEWLINE)?
1004 ;
1005
1006
1007 // -----------------------------------------------------------------
1008 // Whitespace and comments.
1009 // -----------------------------------------------------------------
1010 WHITESPACE
1011 : ('\t' | ' ' | NEWLINE)+ { $channel=HIDDEN; }
1012 ;
1013
1014 SINGLE_LINE_COMMENT
1015 : '//' ~(NEWLINE)* (NEWLINE)? { $channel=HIDDEN; }
1016 ;
1017
1018 MULTI_LINE_COMMENT
1019 : '/*' (options { greedy=false; } : .)* '*/' { $channel=HIDDEN; }
1020 ;
OLDNEW
« no previous file with comments | « no previous file | dart/language/grammar/Makefile » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698