1/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3        Copyright (c) Non, Inc. 1998 -- All Rights Reserved
4
5PROJECT:        C Compiler
6MODULE:         GnuCParser
7FILE:           GnuCParser.g
8
9AUTHOR:         Monty Zukowski (jamz@cdsnet.net) April 28, 1998
10
11DESCRIPTION:
12                This is a grammar for the GNU C compiler.  It is a
13                grammar subclass of StdCParser, overriding only those
14                rules which are different from Standard C.
15
16%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
17
18
19header {
20        package com.sun.gluegen.cgram;
21
22        import java.io.*;
23
24        import antlr.CommonAST;
25        import antlr.DumpASTVisitor;
26}
27
28
29class GnuCParser extends StdCParser;
30
31options
32        {
33        k = 2;
34        exportVocab = GNUC;
35        buildAST = true;
36        ASTLabelType = "TNode";
37
38        // Copied following options from java grammar.
39        codeGenMakeSwitchThreshold = 2;
40        codeGenBitsetTestThreshold = 3;
41        }
42
43
44{
45    // Suppport C++-style single-line comments?
46    public static boolean CPPComments = true;
47
48    // access to symbol table
49    public CSymbolTable symbolTable = new CSymbolTable();
50
51    // source for names to unnamed scopes
52    protected int unnamedScopeCounter = 0;
53
54    public boolean isTypedefName(String name) {
55      boolean returnValue = false;
56      TNode node = symbolTable.lookupNameInCurrentScope(name);
57      for (; node != null; node = (TNode) node.getNextSibling() ) {
58        if(node.getType() == LITERAL_typedef) {
59            returnValue = true;
60            break;
61        }
62      }
63      return returnValue;
64    }
65
66
67    public String getAScopeName() {
68      return "" + (unnamedScopeCounter++);
69    }
70
71    public void pushScope(String scopeName) {
72      symbolTable.pushScope(scopeName);
73    }
74
75    public void popScope() {
76      symbolTable.popScope();
77    }
78
79        int traceDepth = 0;
80        public void reportError(RecognitionException ex) {
81          try {
82            System.err.println("ANTLR Parsing Error: "+ex + " token name:" + tokenNames[LA(1)]);
83            ex.printStackTrace(System.err);
84          }
85	  catch (TokenStreamException e) {
86            System.err.println("ANTLR Parsing Error: "+ex);
87            ex.printStackTrace(System.err);
88          }
89        }
90        public void reportError(String s) {
91            System.err.println("ANTLR Parsing Error from String: " + s);
92        }
93        public void reportWarning(String s) {
94            System.err.println("ANTLR Parsing Warning from String: " + s);
95        }
96        public void match(int t) throws MismatchedTokenException {
97          boolean debugging = false;
98
99          if ( debugging ) {
100           for (int x=0; x<traceDepth; x++) System.out.print(" ");
101           try {
102            System.out.println("Match("+tokenNames[t]+") with LA(1)="+
103                tokenNames[LA(1)] + ((inputState.guessing>0)?" [inputState.guessing "+ inputState.guessing + "]":""));
104           }
105           catch (TokenStreamException e) {
106            System.out.println("Match("+tokenNames[t]+") " + ((inputState.guessing>0)?" [inputState.guessing "+ inputState.guessing + "]":""));
107
108           }
109
110          }
111          try {
112            if ( LA(1)!=t ) {
113                if ( debugging ){
114                    for (int x=0; x<traceDepth; x++) System.out.print(" ");
115                    System.out.println("token mismatch: "+tokenNames[LA(1)]
116                                + "!="+tokenNames[t]);
117                }
118	        throw new MismatchedTokenException(tokenNames, LT(1), t, false, getFilename());
119
120            } else {
121                // mark token as consumed -- fetch next token deferred until LA/LT
122                consume();
123            }
124          }
125          catch (TokenStreamException e) {
126          }
127
128        }
129        public void traceIn(String rname) {
130          traceDepth += 1;
131          for (int x=0; x<traceDepth; x++) System.out.print(" ");
132          try {
133            System.out.println("> "+rname+"; LA(1)==("+ tokenNames[LT(1).getType()]
134                + ") " + LT(1).getText() + " [inputState.guessing "+ inputState.guessing + "]");
135          }
136          catch (TokenStreamException e) {
137          }
138        }
139        public void traceOut(String rname) {
140          for (int x=0; x<traceDepth; x++) System.out.print(" ");
141          try {
142            System.out.println("< "+rname+"; LA(1)==("+ tokenNames[LT(1).getType()]
143                + ") "+LT(1).getText() + " [inputState.guessing "+ inputState.guessing + "]");
144          }
145          catch (TokenStreamException e) {
146          }
147          traceDepth -= 1;
148        }
149
150}
151
152
153translationUnit
154        :       ( externalList )?       /* Empty source files are allowed.  */
155        ;
156asm_expr
157        :       "asm"^
158                ("volatile")? LCURLY expr RCURLY ( SEMI )+
159        ;
160
161idList
162        :       ID ( options{warnWhenFollowAmbig=false;}: COMMA ID )*
163        ;
164
165externalDef
166        :       ( "typedef" | declaration )=> declaration
167        |       ( functionPrefix )=> functionDef
168        |       typelessDeclaration
169        |       asm_expr
170        |       SEMI
171        ;
172
173/* these two are here because GCC allows "cat = 13;" as a valid program! */
174functionPrefix
175                            { String declName; }
176        :       ( (functionDeclSpecifiers)=> ds:functionDeclSpecifiers
177                |  //epsilon
178                )
179                declName = d:declarator[true]
180                ( declaration )* (VARARGS)? ( SEMI )*
181                LCURLY
182        ;
183
184typelessDeclaration
185                        { AST typeMissing = #[NTypeMissing]; }
186        :       initDeclList[typeMissing] SEMI          { ## = #( #[NTypeMissing], ##); }
187        ;
188
189initializer
190        : ( ( ( (initializerElementLabel)=> initializerElementLabel )?
191                ( assignExpr | lcurlyInitializer )  { ## = #( #[NInitializer], ## ); }
192              )
193              | lcurlyInitializer
194              )
195        ;
196
197// GCC allows more specific initializers
198initializerElementLabel
199        :   (   ( LBRACKET ((constExpr VARARGS)=> rangeExpr | constExpr) RBRACKET (ASSIGN)? )
200                | ID COLON
201                | DOT ID ASSIGN
202            )
203                                    { ## = #( #[NInitializerElementLabel], ##) ; }
204        ;
205
206// GCC allows empty initializer lists
207lcurlyInitializer
208        :
209                LCURLY^ (initializerList ( COMMA! )? )? RCURLY
210                            { ##.setType( NLcurlyInitializer ); }
211        ;
212
213initializerList
214        :       initializer ( options{warnWhenFollowAmbig=false;}:COMMA! initializer )*
215        ;
216
217
218declarator[boolean isFunctionDefinition] returns [String declName]
219                                                { declName = ""; }
220        :
221                ( pointerGroup )?
222
223                ( id:ID                         { declName = id.getText(); }
224                | LPAREN declName = declarator[false] RPAREN
225                )
226
227                ( declaratorParamaterList[isFunctionDefinition, declName]
228                | LBRACKET ( expr )? RBRACKET
229                )*
230                                                { ## = #( #[NDeclarator], ## ); }
231        ;
232
233declaratorParamaterList[boolean isFunctionDefinition, String declName]
234        :
235                LPAREN^
236                                                {
237                                                    if (isFunctionDefinition) {
238                                                        pushScope(declName);
239                                                    }
240                                                    else {
241                                                        pushScope("!"+declName);
242                                                    }
243                                                }
244                (
245                        (declSpecifiers)=> parameterTypeList
246                        | (idList)?
247                )
248                                                {
249                                                popScope();
250                                                }
251                ( COMMA! )?
252                RPAREN
253                                                { ##.setType(NParameterTypeList); }
254        ;
255
256parameterTypeList
257        :       parameterDeclaration
258                (   options {
259                            warnWhenFollowAmbig = false;
260                        } :
261                  ( COMMA | SEMI )
262                  parameterDeclaration
263                )*
264                ( ( COMMA | SEMI )
265                  VARARGS
266                )?
267        ;
268
269
270declarationList
271         :       (               options {   // this loop properly aborts when
272                                            // it finds a non-typedefName ID MBZ
273                                            warnWhenFollowAmbig = false;
274                                        } :
275
276                localLabelDeclaration
277                |  ( declarationPredictor )=> declaration
278                )+
279        ;
280localLabelDeclaration
281        :       ( //GNU note:  any __label__ declarations must come before regular declarations.
282                "__label__"^ ID (options{warnWhenFollowAmbig=false;}: COMMA! ID)* ( COMMA! )? ( SEMI! )+
283                )
284        ;
285
286
287declaration
288                                        { AST ds1 = null; }
289        :       ds:declSpecifiers       { ds1 = astFactory.dupList(#ds); }
290                (
291                    initDeclList[ds1]
292                )?
293                ( SEMI )+
294                                        { ## = #( #[NDeclaration], ##); }
295
296        ;
297
298functionStorageClassSpecifier
299        :       "extern"
300        |       "static"
301        |       "inline"
302        ;
303
304typeSpecifier [int specCount] returns [int retSpecCount]
305                                                        { retSpecCount = specCount + 1; }
306        :
307        ( "void"
308        |       "char"
309        |       "short"
310        |       "int"
311        |       "__int32"
312        |       "__int64"
313        |       "long"
314        |       "float"
315        |       "double"
316        |       "signed"
317        |       "unsigned"
318        |       structOrUnionSpecifier  ( options{warnWhenFollowAmbig=false;}: attributeDecl )*
319        |       enumSpecifier
320        |       { specCount==0 }? typedefName
321        |       "typeof"^ LPAREN
322                ( ( typeName )=> typeName
323                | expr
324                )
325                RPAREN
326        |       "__complex"
327        )
328        ;
329
330
331structOrUnionSpecifier
332                                        { String scopeName; }
333        :       sou:structOrUnion!
334                ( ( ID LCURLY )=> i:ID l:LCURLY
335                                            {
336                                            scopeName = #sou.getText() + " " + #i.getText();
337                                            #l.setText(scopeName);
338                                            pushScope(scopeName);
339                                            }
340                        ( structDeclarationList )?
341                                            { popScope();}
342                        RCURLY
343                |   l1:LCURLY
344                                            {
345                                            scopeName = getAScopeName();
346                                            #l1.setText(scopeName);
347                                            pushScope(scopeName);
348                                            }
349                    ( structDeclarationList )?
350                                            { popScope(); }
351                    RCURLY
352                | ID
353                )
354                                            {
355                                            ## = #( #sou, ## );
356                                            }
357        ;
358
359
360structDeclaration
361        :       specifierQualifierList structDeclaratorList ( COMMA! )? ( SEMI! )+
362        ;
363
364structDeclaratorList
365        :       structDeclarator ( options{warnWhenFollowAmbig=false;}: COMMA! structDeclarator )*
366        ;
367
368structDeclarator
369        :       ( declarator[false] )?
370                ( COLON constExpr )?
371                ( attributeDecl )*
372                                    { ## = #( #[NStructDeclarator], ##); }
373        ;
374
375
376
377enumSpecifier
378        :       "enum"^
379                ( ( ID LCURLY )=> i:ID LCURLY enumList[i.getText()] RCURLY
380                | LCURLY enumList["anonymous"] RCURLY
381                | ID
382                )
383        ;
384enumList[String enumName]
385        :       enumerator[enumName] ( options{warnWhenFollowAmbig=false;}: COMMA! enumerator[enumName] )* ( COMMA! )?
386        ;
387
388
389initDeclList[AST declarationSpecifiers]
390        :       initDecl[declarationSpecifiers]
391                ( options{warnWhenFollowAmbig=false;}: COMMA! initDecl[declarationSpecifiers] )*
392                ( COMMA! )?
393        ;
394
395initDecl[AST declarationSpecifiers]
396                                        { String declName = ""; }
397        :       declName = d:declarator[false]
398                                        {   AST ds1, d1;
399                                            ds1 = astFactory.dupList(declarationSpecifiers);
400                                            d1 = astFactory.dupList(#d);
401                                            symbolTable.add(declName, #(null, ds1, d1) );
402                                        }
403                ( attributeDecl )*
404                ( ASSIGN initializer
405                | COLON expr
406                )?
407                                        { ## = #( #[NInitDecl], ## ); }
408        ;
409
410attributeDecl
411        :       "__attribute"^ LPAREN LPAREN attributeList RPAREN RPAREN
412                | "asm"^ LPAREN stringConst RPAREN { ##.setType( NAsmAttribute ); }
413        ;
414
415attributeList
416        :       attribute ( options{warnWhenFollowAmbig=false;}: COMMA attribute)*  ( COMMA )?
417        ;
418
419attribute
420        :       ( ~(LPAREN | RPAREN | COMMA)
421                |  LPAREN attributeList RPAREN
422                )*
423        ;
424compoundStatement[String scopeName]
425        :       LCURLY^
426
427                            {
428                                pushScope(scopeName);
429                            }
430                (       //this ambiguity is ok, declarationList and nestedFunctionDef end properly
431                        options {
432                            warnWhenFollowAmbig = false;
433                        } :
434                    ( "typedef" | "__label__" | declaration )=> declarationList
435                    | (nestedFunctionDef)=> nestedFunctionDef
436                )*
437                ( statementList )?
438                            { popScope(); }
439                RCURLY
440                            { ##.setType( NCompoundStatement ); ##.setAttribute( "scopeName", scopeName ); }
441        ;
442
443nestedFunctionDef
444                            { String declName; }
445        :       ( "auto" )? //only for nested functions
446                ( (functionDeclSpecifiers)=> ds:functionDeclSpecifiers
447                )?
448                declName = d:declarator[false]
449                            {
450                            AST d2, ds2;
451                            d2 = astFactory.dupList(#d);
452                            ds2 = astFactory.dupList(#ds);
453                            symbolTable.add(declName, #(null, ds2, d2));
454                            pushScope(declName);
455                            }
456                ( declaration )*
457                            { popScope(); }
458                compoundStatement[declName]
459                            { ## = #( #[NFunctionDef], ## );}
460        ;
461
462statement
463        :       SEMI                    // Empty statements
464
465        |       compoundStatement[getAScopeName()]       // Group of statements
466
467        |       expr SEMI!               { ## = #( #[NStatementExpr], ## );} // Expressions
468
469// Iteration statements:
470
471        |       "while"^ LPAREN! expr RPAREN! statement
472        |       "do"^ statement "while"! LPAREN! expr RPAREN! SEMI!
473        |!       "for"
474                LPAREN ( e1:expr )? SEMI ( e2:expr )? SEMI ( e3:expr )? RPAREN
475                s:statement
476                                    {
477                                        if ( #e1 == null) { #e1 = (TNode) #[ NEmptyExpression ]; }
478                                        if ( #e2 == null) { #e2 = (TNode) #[ NEmptyExpression ]; }
479                                        if ( #e3 == null) { #e3 = (TNode) #[ NEmptyExpression ]; }
480                                        ## = #( #[LITERAL_for, "for"], #e1, #e2, #e3, #s );
481                                    }
482
483
484// Jump statements:
485
486        |       "goto"^ expr SEMI!
487        |       "continue" SEMI!
488        |       "break" SEMI!
489        |       "return"^ ( expr )? SEMI!
490
491
492        |       ID COLON! (options {warnWhenFollowAmbig=false;}: statement)?  { ## = #( #[NLabel], ## ); }
493// GNU allows range expressions in case statements
494        |       "case"^ ((constExpr VARARGS)=> rangeExpr | constExpr) COLON! ( options{warnWhenFollowAmbig=false;}:statement )?
495        |       "default"^ COLON! ( options{warnWhenFollowAmbig=false;}: statement )?
496
497// Selection statements:
498
499        |       "if"^
500                 LPAREN! expr RPAREN! statement
501                ( //standard if-else ambiguity
502                        options {
503                            warnWhenFollowAmbig = false;
504                        } :
505                "else" statement )?
506        |       "switch"^ LPAREN! expr RPAREN! statement
507        ;
508
509
510
511conditionalExpr
512        :       logicalOrExpr
513                ( QUESTION^ (expr)? COLON conditionalExpr )?
514        ;
515
516rangeExpr   //used in initializers only
517        :  constExpr VARARGS constExpr
518                                { ## = #(#[NRangeExpr], ##); }
519        ;
520
521castExpr
522        :       ( LPAREN typeName RPAREN )=>
523                LPAREN^ typeName RPAREN ( castExpr | lcurlyInitializer )
524                            { ##.setType(NCast); }
525
526        |       unaryExpr
527        ;
528nonemptyAbstractDeclarator
529        :   (
530                pointerGroup
531                (   (LPAREN
532                    (   nonemptyAbstractDeclarator
533                        | parameterTypeList
534                    )?
535                    ( COMMA! )?
536                    RPAREN)
537                | (LBRACKET (expr)? RBRACKET)
538                )*
539
540            |   (   (LPAREN
541                    (   nonemptyAbstractDeclarator
542                        | parameterTypeList
543                    )?
544                    ( COMMA! )?
545                    RPAREN)
546                | (LBRACKET (expr)? RBRACKET)
547                )+
548            )
549                            {   ## = #( #[NNonemptyAbstractDeclarator], ## ); }
550
551        ;
552
553
554
555unaryExpr
556        :       postfixExpr
557        |       INC^ castExpr
558        |       DEC^ castExpr
559        |       u:unaryOperator castExpr { ## = #( #[NUnaryExpr], ## ); }
560
561        |       "sizeof"^
562                ( ( LPAREN typeName )=> LPAREN typeName RPAREN
563                | unaryExpr
564                )
565        |       "__alignof"^
566                ( ( LPAREN typeName )=> LPAREN typeName RPAREN
567                | unaryExpr
568                )
569        |       gnuAsmExpr
570        ;
571
572unaryOperator
573        :       BAND
574        |       STAR
575        |       PLUS
576        |       MINUS
577        |       BNOT    //also stands for complex conjugation
578        |       LNOT
579        |       LAND    //for label dereference (&&label)
580        |       "__real"
581        |       "__imag"
582        ;
583
584gnuAsmExpr
585        :       "asm"^ ("volatile")?
586                LPAREN stringConst
587                ( options { warnWhenFollowAmbig = false; }:
588                  COLON (strOptExprPair ( COMMA strOptExprPair)* )?
589                  ( options { warnWhenFollowAmbig = false; }:
590                    COLON (strOptExprPair ( COMMA strOptExprPair)* )?
591                  )?
592                )?
593                ( COLON stringConst ( COMMA stringConst)* )?
594                RPAREN
595                                { ##.setType(NGnuAsmExpr); }
596        ;
597
598//GCC requires the PARENs
599strOptExprPair
600        :  stringConst ( LPAREN expr RPAREN )?
601        ;
602
603
604primaryExpr
605        :       ID
606        |       Number
607        |       charConst
608        |       stringConst
609// JTC:
610// ID should catch the enumerator
611// leaving it in gives ambiguous err
612//      | enumerator
613        |       (LPAREN LCURLY) => LPAREN^ compoundStatement[getAScopeName()] RPAREN
614        |       LPAREN^ expr RPAREN        { ##.setType(NExpressionGroup); }
615        ;
616
617
618{
619        import java.io.*;
620        import java.util.*;
621        import antlr.*;
622}
623
624class GnuCLexer extends StdCLexer;
625options
626        {
627        k = 3;
628        importVocab = GNUC;
629        testLiterals = false;
630        }
631tokens {
632        LITERAL___extension__ = "__extension__";
633}
634
635{
636  public void initialize(String src)
637  {
638    setOriginalSource(src);
639    initialize();
640  }
641
642  public void initialize()
643  {
644    literals.put(new ANTLRHashString("__alignof__", this), new Integer(LITERAL___alignof));
645    literals.put(new ANTLRHashString("__asm", this), new Integer(LITERAL_asm));
646    literals.put(new ANTLRHashString("__asm__", this), new Integer(LITERAL_asm));
647    literals.put(new ANTLRHashString("__attribute__", this), new Integer(LITERAL___attribute));
648    literals.put(new ANTLRHashString("__complex__", this), new Integer(LITERAL___complex));
649    literals.put(new ANTLRHashString("__const", this), new Integer(LITERAL_const));
650    literals.put(new ANTLRHashString("__const__", this), new Integer(LITERAL_const));
651    literals.put(new ANTLRHashString("__imag__", this), new Integer(LITERAL___imag));
652    literals.put(new ANTLRHashString("__inline", this), new Integer(LITERAL_inline));
653    literals.put(new ANTLRHashString("__inline__", this), new Integer(LITERAL_inline));
654    literals.put(new ANTLRHashString("__real__", this), new Integer(LITERAL___real));
655    literals.put(new ANTLRHashString("__signed", this), new Integer(LITERAL_signed));
656    literals.put(new ANTLRHashString("__signed__", this), new Integer(LITERAL_signed));
657    literals.put(new ANTLRHashString("__typeof", this), new Integer(LITERAL_typeof));
658    literals.put(new ANTLRHashString("__typeof__", this), new Integer(LITERAL_typeof));
659    literals.put(new ANTLRHashString("__volatile", this), new Integer(LITERAL_volatile));
660    literals.put(new ANTLRHashString("__volatile__", this), new Integer(LITERAL_volatile));
661  }
662
663
664  LineObject lineObject = new LineObject();
665  String originalSource = "";
666  PreprocessorInfoChannel preprocessorInfoChannel = new PreprocessorInfoChannel();
667  int tokenNumber = 0;
668  boolean countingTokens = true;
669  int deferredLineCount = 0;
670  List defines = new ArrayList();
671
672  public void setCountingTokens(boolean ct)
673  {
674    countingTokens = ct;
675    if ( countingTokens ) {
676      tokenNumber = 0;
677    }
678    else {
679      tokenNumber = 1;
680    }
681  }
682
683  public void setOriginalSource(String src)
684  {
685    originalSource = src;
686    lineObject.setSource(src);
687  }
688  public void setSource(String src)
689  {
690    lineObject.setSource(src);
691  }
692
693  public PreprocessorInfoChannel getPreprocessorInfoChannel()
694  {
695    return preprocessorInfoChannel;
696  }
697
698  public void setPreprocessingDirective(String pre)
699  {
700    preprocessorInfoChannel.addLineForTokenNumber( pre, new Integer(tokenNumber) );
701  }
702
703  public void addDefine(String name, String value)
704  {
705    defines.add(new Define(name, value));
706  }
707
708  /** Returns a list of Define objects corresponding to the
709      preprocessor definitions seen during parsing. */
710  public List getDefines() {
711    return defines;
712  }
713
714  protected Token makeToken(int t)
715  {
716    if ( t != Token.SKIP && countingTokens) {
717        tokenNumber++;
718    }
719    CToken tok = (CToken) super.makeToken(t);
720    tok.setLine(lineObject.line);
721    tok.setSource(lineObject.source);
722    tok.setTokenNumber(tokenNumber);
723
724    lineObject.line += deferredLineCount;
725    deferredLineCount = 0;
726    return tok;
727  }
728
729    public void deferredNewline() {
730        deferredLineCount++;
731    }
732
733    public void newline() {
734        lineObject.newline();
735    }
736
737
738
739
740
741
742}
743Whitespace
744        :       ( ( ' ' | '\t' | '\014')
745                | "\r\n"                { newline(); }
746                | ( '\n' | '\r' )       { newline();    }
747                )                       { _ttype = Token.SKIP;  }
748        ;
749
750
751protected
752Escape
753        :       '\\'
754                ( options{warnWhenFollowAmbig=false;}:
755                  ~('0'..'7' | 'x')
756                | ('0'..'3') ( options{warnWhenFollowAmbig=false;}: Digit )*
757                | ('4'..'7') ( options{warnWhenFollowAmbig=false;}: Digit )*
758                | 'x' ( options{warnWhenFollowAmbig=false;}: Digit | 'a'..'f' | 'A'..'F' )+
759                )
760        ;
761
762protected IntSuffix
763        :   'L'
764            | 'l'
765            | 'U'
766            | 'u'
767            | 'I'
768            | 'i'
769            | 'J'
770            | 'j'
771        ;
772protected NumberSuffix
773        :
774            IntSuffix
775            | 'F'
776            | 'f'
777        ;
778
779Number
780        :       ( ( Digit )+ ( '.' | 'e' | 'E' ) )=> ( Digit )+
781                ( '.' ( Digit )* ( Exponent )?
782                | Exponent
783                )
784                ( NumberSuffix
785                )*
786
787        |       ( "..." )=> "..."       { _ttype = VARARGS;     }
788
789        |       '.'                     { _ttype = DOT; }
790                ( ( Digit )+ ( Exponent )?
791                                        { _ttype = Number;   }
792                    ( NumberSuffix
793                    )*
794                )?
795
796        |       '0' ( '0'..'7' )*
797                ( NumberSuffix
798                )*
799
800        |       '1'..'9' ( Digit )*
801                ( NumberSuffix
802                )*
803
804        |       '0' ( 'x' | 'X' ) ( 'a'..'f' | 'A'..'F' | Digit )+
805                ( IntSuffix
806                )*
807        ;
808
809IDMEAT
810        :
811                i:ID                {
812
813                                        if ( i.getType() == LITERAL___extension__ ) {
814                                                $setType(Token.SKIP);
815                                        }
816                                        else {
817                                                $setType(i.getType());
818                                        }
819
820                                    }
821        ;
822
823protected ID
824        options
825                {
826                testLiterals = true;
827                }
828        :       ( 'a'..'z' | 'A'..'Z' | '_' | '$')
829                ( 'a'..'z' | 'A'..'Z' | '_' | '$' | '0'..'9' )*
830        ;
831
832WideCharLiteral
833        :
834                'L' CharLiteral
835                                { $setType(CharLiteral); }
836        ;
837
838
839
840WideStringLiteral
841        :
842                'L' StringLiteral
843                                { $setType(StringLiteral); }
844        ;
845
846StringLiteral
847        :
848                '"'
849                ( ('\\' ~('\n'))=> Escape
850                | ( '\r'        { newline(); }
851                  | '\n'        {
852                                newline();
853                                }
854                  | '\\' '\n'   {
855                                newline();
856                                }
857                  )
858                | ~( '"' | '\r' | '\n' | '\\' )
859                )*
860                '"'
861        ;
862
863
864
865
866