001    /* This file was generated with JastAdd2 (http://jastadd.org) version R20130213 */
002    package AST;
003    
004    import java.util.HashSet;
005    import java.io.File;
006    import java.util.*;
007    import beaver.*;
008    import java.util.ArrayList;
009    import java.util.zip.*;
010    import java.io.*;
011    import java.io.FileNotFoundException;
012    import java.util.Collection;
013    /**
014     * A NumericLiteral is a raw literal, produced by the parser.
015     * NumericLiterals are rewritten to the best matching concrete
016     * numeric literal kind, or IllegalLiteral.
017     * @production NumericLiteral : {@link Literal};
018     * @ast node
019     * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.ast:18
020     */
021    public class NumericLiteral extends Literal implements Cloneable {
022      /**
023       * @apilevel low-level
024       */
025      public void flushCache() {
026      }
027      /**
028       * @apilevel internal
029       */
030      public void flushCollectionCache() {
031      }
032      /**
033       * @apilevel internal
034       */
035      @SuppressWarnings({"unchecked", "cast"})
036      public NumericLiteral clone() throws CloneNotSupportedException {
037        NumericLiteral node = (NumericLiteral)super.clone();
038        node.type_computed = false;
039        node.type_value = null;
040        node.in$Circle(false);
041        node.is$Final(false);
042        return node;
043      }
044    /**
045     * @apilevel internal
046     */
047      @SuppressWarnings({"unchecked", "cast"})
048    public NumericLiteral copy() {
049      
050      try {
051        NumericLiteral node = (NumericLiteral) clone();
052        node.parent = null;
053        if(children != null)
054          node.children = (ASTNode[]) children.clone();
055        
056        return node;
057      } catch (CloneNotSupportedException e) {
058        throw new Error("Error: clone not supported for " + getClass().getName());
059      }
060      
061    }/**
062     * Create a deep copy of the AST subtree at this node.
063     * The copy is dangling, i.e. has no parent.
064     * @return dangling copy of the subtree at this node
065     * @apilevel low-level
066     */
067      @SuppressWarnings({"unchecked", "cast"})
068    public NumericLiteral fullCopy() {
069      
070      NumericLiteral tree = (NumericLiteral) copy();
071      if (children != null) {
072        for (int i = 0; i < children.length; ++i) {
073          
074          ASTNode child = (ASTNode) children[i];
075          if(child != null) {
076            child = child.fullCopy();
077            tree.setChild(child, i);
078          }
079        }
080      }
081      return tree;
082      
083    }  /**
084       * @ast method 
085       * @aspect Literals
086       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:321
087       */
088      
089    
090        public static final int DECIMAL = 0;
091      /**
092       * @ast method 
093       * @aspect Literals
094       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:322
095       */
096      
097        public static final int HEXADECIMAL = 1;
098      /**
099       * @ast method 
100       * @aspect Literals
101       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:323
102       */
103      
104       public static final int OCTAL = 2;
105      /**
106       * @ast method 
107       * @aspect Literals
108       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:324
109       */
110      
111       public static final int BINARY = 3;
112      /**
113        * The trimmed digits.
114        * @ast method 
115       * @aspect Literals
116       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:382
117       */
118      
119    
120       /**
121        * The trimmed digits.
122        */
123       protected String digits = "";
124      /**
125        * Sets the trimmed digits of this literal.
126        * @ast method 
127       * @aspect Literals
128       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:387
129       */
130      public void setDigits(String digits) {
131               this.digits = digits;
132       }
133      /**
134        * The literal kind tells which kind of literal it is;
135        * it's either a DECIMAL, HEXADECIMAL, OCTAL or BINARY literal.
136        * @ast method 
137       * @aspect Literals
138       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:401
139       */
140      
141    
142       /**
143        * The literal kind tells which kind of literal it is;
144        * it's either a DECIMAL, HEXADECIMAL, OCTAL or BINARY literal.
145        */
146       protected int kind = NumericLiteral.DECIMAL;
147      /**
148        * Sets the literal kind.
149        * @ast method 
150       * @aspect Literals
151       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:406
152       */
153      public void setKind(int kind) {
154               this.kind = kind;
155       }
156      /**
157       * @ast method 
158       * @aspect Literals
159       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:489
160       */
161      
162               private StringBuffer buf = new StringBuffer();
163      /**
164       * @ast method 
165       * @aspect Literals
166       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:490
167       */
168      
169               private int idx = 0;
170      /**
171       * @ast method 
172       * @aspect Literals
173       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:491
174       */
175      
176               private boolean whole;
177      /**
178       * @ast method 
179       * @aspect Literals
180       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:492
181       */
182      // have whole part?
183               private boolean fraction;
184      /**
185       * @ast method 
186       * @aspect Literals
187       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:493
188       */
189      // have fraction part?
190               private boolean exponent;
191      /**
192       * @ast method 
193       * @aspect Literals
194       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:494
195       */
196      // have exponent part?
197               private boolean floating;
198      /**
199       * @ast method 
200       * @aspect Literals
201       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:495
202       */
203      // is floating point?
204               private boolean isFloat;
205      /**
206       * @ast method 
207       * @aspect Literals
208       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:496
209       */
210      
211               private boolean isLong;
212      /**
213                * @return a readable name to describe this literal.
214                * @ast method 
215       * @aspect Literals
216       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:501
217       */
218      
219    
220               /**
221                * @return a readable name to describe this literal.
222                */
223               private String name() {
224                       String name;
225                       switch (kind) {
226                               case DECIMAL:
227                                       name = "decimal";
228                                       break;
229                               case HEXADECIMAL:
230                                       name = "hexadecimal";
231                                       break;
232                               case OCTAL:
233                                       name = "octal";
234                                       break;
235                               case BINARY:
236                               default:
237                                       name = "binary";
238                                       break;
239                       }
240                       if (floating)
241                               return name+" floating point";
242                       else
243                               return name;
244               }
245      /**
246                * The next character in the literal is a significant character;
247                * push it onto the buffer.
248                * @ast method 
249       * @aspect Literals
250       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:528
251       */
252      
253    
254               /**
255                * The next character in the literal is a significant character;
256                * push it onto the buffer.
257                */
258               private void pushChar() {
259                       buf.append(getLITERAL().charAt(idx++));
260               }
261      /**
262                * Skip ahead n chracters in the literal.
263                * @ast method 
264       * @aspect Literals
265       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:535
266       */
267      
268    
269               /**
270                * Skip ahead n chracters in the literal.
271                */
272               private void skip(int n) {
273                       idx += n;
274               }
275      /**
276                * @return true if there exists at least n more characters
277                * in the literal
278                * @ast method 
279       * @aspect Literals
280       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:543
281       */
282      
283    
284               /**
285                * @return true if there exists at least n more characters
286                * in the literal
287                */
288               private boolean have(int n) {
289                       return getLITERAL().length() >= idx+n;
290               }
291      /**
292                * Look at the n'th next character.
293                * @ast method 
294       * @aspect Literals
295       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:550
296       */
297      
298    
299               /**
300                * Look at the n'th next character.
301                */
302               private char peek(int n) {
303                       return getLITERAL().charAt(idx+n);
304               }
305      /**
306                * @return true if the character c is a decimal digit
307                * @ast method 
308       * @aspect Literals
309       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:557
310       */
311      
312    
313               /**
314                * @return true if the character c is a decimal digit
315                */
316               private static final boolean isDecimalDigit(char c) {
317                       return c == '_' || c >= '0' && c <= '9';
318               }
319      /**
320                * @return true if the character c is a hexadecimal digit
321                * @ast method 
322       * @aspect Literals
323       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:564
324       */
325      
326    
327               /**
328                * @return true if the character c is a hexadecimal digit
329                */
330               private static final boolean isHexadecimalDigit(char c) {
331                       return c == '_' || c >= '0' && c <= '9' ||
332                               c >= 'a' && c <= 'f' ||
333                               c >= 'A' && c <= 'F';
334               }
335      /**
336                * @return true if the character c is a binary digit
337                * @ast method 
338       * @aspect Literals
339       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:573
340       */
341      
342    
343               /**
344                * @return true if the character c is a binary digit
345                */
346               private static final boolean isBinaryDigit(char c) {
347                       return c == '_' || c == '0' || c == '1';
348               }
349      /**
350                * @return true if the character c is an underscore
351                * @ast method 
352       * @aspect Literals
353       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:580
354       */
355      
356    
357               /**
358                * @return true if the character c is an underscore
359                */
360               private static final boolean isUnderscore(char c) {
361                       return c == '_';
362               }
363      /**
364                * Parse a literal. If there is a syntax error in the literal,
365                * an IllegalLiteral will be returned.
366                * @ast method 
367       * @aspect Literals
368       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:588
369       */
370      
371    
372               /**
373                * Parse a literal. If there is a syntax error in the literal,
374                * an IllegalLiteral will be returned.
375                */
376               public Literal parse() {
377                       if (getLITERAL().length() == 0)
378                               throw new IllegalStateException("Empty NumericLiteral");
379    
380                       kind = classifyLiteral();
381    
382                       Literal literal;
383                       if (!floating)
384                               literal = parseDigits();
385                       else
386                               literal = parseFractionPart();
387                       literal.setStart(LITERALstart);
388                       literal.setEnd(LITERALend);
389                       return literal;
390               }
391      /**
392                * Classify the literal.
393                *
394                * @return either DECIMAL, HEXADECIMAL or BINARY
395                * @ast method 
396       * @aspect Literals
397       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:609
398       */
399      
400    
401               /**
402                * Classify the literal.
403                *
404                * @return either DECIMAL, HEXADECIMAL or BINARY
405                */
406               private int classifyLiteral() {
407                       if (peek(0) == '.') {
408                               floating = true;
409                               return DECIMAL;
410                       } else if (peek(0) == '0') {
411                               if (!have(2)) {
412                                       // the only 1-length string that starts with 0 (obvious!)
413                                       return DECIMAL;
414                               } else if (peek(1) == 'x' || peek(1) == 'X') {
415                                       skip(2);
416                                       return HEXADECIMAL;
417                               } else if (peek(1) == 'b' || peek(1) == 'B') {
418                                       skip(2);
419                                       return BINARY;
420                               } else {
421                                       return DECIMAL;
422                               }
423                       } else {
424                               return DECIMAL;
425                       }
426               }
427      /**
428                * If the current character is an underscore, the previous and next
429                * characters need to be valid digits or underscores.
430                *
431                * @return true if the underscore is misplaced
432                * @ast method 
433       * @aspect Literals
434       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:637
435       */
436      
437    
438               /**
439                * If the current character is an underscore, the previous and next
440                * characters need to be valid digits or underscores.
441                *
442                * @return true if the underscore is misplaced
443                */
444               private boolean misplacedUnderscore() {
445                       // first and last characters are never allowed to be an underscore
446                       if (idx == 0 || idx+1 == getLITERAL().length())
447                               return true;
448    
449                       switch (kind) {
450                               case DECIMAL:
451                                       return !(isDecimalDigit(peek(-1)) && isDecimalDigit(peek(1)));
452                               case HEXADECIMAL:
453                                       return !(isHexadecimalDigit(peek(-1)) && isHexadecimalDigit(peek(1)));
454                               case BINARY:
455                                       return !(isBinaryDigit(peek(-1)) && isBinaryDigit(peek(1)));
456                       }
457                       throw new IllegalStateException("Unexpected literal kind");
458               }
459      /**
460                * Report an illegal digit.
461                * @ast method 
462       * @aspect Literals
463       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:656
464       */
465      
466    
467               /**
468                * Report an illegal digit.
469                */
470               private Literal syntaxError(String msg) {
471                       String err = "in "+name()+" literal "+
472                               "\""+getLITERAL()+"\""+": "+msg;
473                       return new IllegalLiteral(err);
474               }
475      /**
476       * @ast method 
477       * @aspect Literals
478       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:662
479       */
480      
481    
482               private Literal unexpectedCharacter(char c) {
483                       return syntaxError("unexpected character '"+c+"'; not a valid digit");
484               }
485      /**
486                * Returns a string of only the lower case digits of the
487                * parsed numeric literal.
488                * @ast method 
489       * @aspect Literals
490       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:670
491       */
492      
493    
494               /**
495                * Returns a string of only the lower case digits of the
496                * parsed numeric literal.
497                */
498               private String getLiteralString() {
499                       return buf.toString().toLowerCase();
500               }
501      /**
502                * Parse and build an IntegerLiteral, LongLiteral,
503                * FloatingPointLiteral or DoubleLiteral. Returns an
504                * IllegalLiteral if the numeric literal can not be
505                * parsed.
506                *
507                * Note: does not perform bounds checks.
508                *
509                * @return a concrete literal on success, or an IllegalLiteral if there is a syntax error
510                * @ast method 
511       * @aspect Literals
512       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:684
513       */
514      
515    
516               /**
517                * Parse and build an IntegerLiteral, LongLiteral,
518                * FloatingPointLiteral or DoubleLiteral. Returns an
519                * IllegalLiteral if the numeric literal can not be
520                * parsed.
521                *
522                * Note: does not perform bounds checks.
523                *
524                * @return a concrete literal on success, or an IllegalLiteral if there is a syntax error
525                */
526               private Literal buildLiteral() {
527                       NumericLiteral literal;
528                       setDigits(buf.toString().toLowerCase());
529    
530                       if (!floating) {
531                               if (!whole)
532                                       return syntaxError("at least one digit is required");
533    
534                               // check if the literal is octal, and if so report illegal digits
535                               if (kind == DECIMAL) {
536                                       if (digits.charAt(0) == '0') {
537                                               kind = OCTAL;
538                                               for (int idx = 1; idx < digits.length(); ++idx) {
539                                                       char c = digits.charAt(idx);
540                                                       if (c < '0' || c > '7')
541                                                               return unexpectedCharacter(c);
542                                               }
543                                       }
544                               }
545                               
546                               if (isLong)
547                                       literal = new LongLiteral(getLITERAL());
548                               else
549                                       literal = new IntegerLiteral(getLITERAL());
550                       } else {
551                               if (kind == HEXADECIMAL && !exponent)
552                                       return syntaxError("exponent is required");
553    
554                               if (!(whole || fraction))
555                                       return syntaxError("at least one digit is required in "+
556                                                       "either the whole or fraction part");
557    
558                               if (kind == HEXADECIMAL)
559                                       digits = "0x"+digits;// digits parsed with Float or Double
560    
561                               if (isFloat)
562                                       literal = new FloatingPointLiteral(getLITERAL());
563                               else
564                                       literal = new DoubleLiteral(getLITERAL());
565                       }
566    
567                       literal.setDigits(getDigits());
568                       literal.setKind(getKind());
569                       return literal;
570               }
571      /**
572       * @ast method 
573       * @aspect Literals
574       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:730
575       */
576      
577    
578               private Literal parseDigits() {
579                       // while we have at least one more character/digit
580                       while (have(1)) {
581                               char c = peek(0);
582                               switch (c) {
583                                       case '_':
584                                               if (misplacedUnderscore())
585                                                       return syntaxError("misplaced underscore - underscores may only "+
586                                                                       "be used within sequences of digits");
587                                               skip(1);
588                                               continue;
589                                       case '.':
590                                               if (kind != DECIMAL && kind != HEXADECIMAL)
591                                                       return unexpectedCharacter(c);
592                                               return parseFractionPart();
593                                       case 'l':
594                                       case 'L':
595                                               if (have(2))
596                                                       return syntaxError("extra digits/characters "+
597                                                               "after suffix "+c);
598                                               isLong = true;
599                                               skip(1);
600                                               continue;
601                                       case 'f':
602                                       case 'F':
603                                               if (kind == BINARY)
604                                                       return unexpectedCharacter(c);
605                                               isFloat = true;
606                                       case 'd':
607                                       case 'D':
608                                               if (kind == BINARY)
609                                                       return unexpectedCharacter(c);
610                                               if (kind != HEXADECIMAL) {
611                                                       if (have(2))
612                                                               return syntaxError("extra digits/characters "+
613                                                                               "after type suffix "+c);
614                                                       floating = true;
615                                                       skip(1);
616                                               } else {
617                                                       whole = true;
618                                                       pushChar();
619                                               }
620                                               continue;
621                               }
622    
623                               switch (kind) {
624                                       case DECIMAL:
625                                               if (c == 'e' || c == 'E') {
626                                                       return parseExponentPart();
627    
628                                               } else if (c == 'f' || c == 'F') {
629                                                       if (have(2))
630                                                               return syntaxError("extra digits/characters "+
631                                                                               "after type suffix "+c);
632                                                       floating = true;
633                                                       isFloat = true;
634                                                       skip(1);
635                                               } else if (c == 'd' || c == 'D') {
636                                                       if (have(2))
637                                                               return syntaxError("extra digits/characters "+
638                                                                               "after type suffix "+c);
639                                                       floating = true;
640                                                       skip(1);
641                                               } else {
642                                                       if (!isDecimalDigit(c))
643                                                               return unexpectedCharacter(c);
644                                                       whole = true;
645                                                       pushChar();
646                                               }
647                                               continue;
648                                       case HEXADECIMAL:
649                                               if (c == 'p' || c == 'P')
650                                                       return parseExponentPart();
651    
652                                               if (!isHexadecimalDigit(c))
653                                                       return unexpectedCharacter(c);
654                                               whole = true;
655                                               pushChar();
656                                               continue;
657                                       case BINARY:
658                                               if (!isBinaryDigit(c))
659                                                       return unexpectedCharacter(c);
660                                               whole = true;
661                                               pushChar();
662                                               continue;
663                               }
664                       }
665    
666                       return buildLiteral();
667               }
668      /**
669       * @ast method 
670       * @aspect Literals
671       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:821
672       */
673      
674    
675               private Literal parseFractionPart() {
676                       floating = true;
677    
678                       // current char is the decimal period
679                       pushChar();
680    
681                       // while we have at least one more character/digit
682                       while (have(1)) {
683                               char c = peek(0);
684                               switch (c) {
685                                       case '_':
686                                               if (misplacedUnderscore())
687                                                       return syntaxError("misplaced underscore - underscores may only "+
688                                                                       "be used as separators within sequences of valid digits");
689                                               skip(1);
690                                               continue;
691                                       case '.':
692                                               return syntaxError("multiple decimal periods are not allowed");
693                               }
694    
695                               if (kind == DECIMAL) {
696                                       if (c == 'e' || c == 'E') {
697                                               return parseExponentPart();
698    
699                                       } else if (c == 'f' || c == 'F') {
700                                               if (have(2))
701                                                       return syntaxError("extra digits/characters "+
702                                                                       "after type suffix "+c);
703                                               floating = true;
704                                               isFloat = true;
705                                               skip(1);
706                                       } else if (c == 'd' || c == 'D') {
707                                               if (have(2))
708                                                       return syntaxError("extra digits/characters "+
709                                                                       "after type suffix "+c);
710                                               floating = true;
711                                               skip(1);
712                                       } else {
713                                               if (!isDecimalDigit(c))
714                                                       return unexpectedCharacter(c);
715                                               pushChar();
716                                               fraction = true;
717                                       }
718                               } else { // kind == HEXADECIMAL
719                                       if (c == 'p' || c == 'P')
720                                               return parseExponentPart();
721    
722                                       if (!isHexadecimalDigit(c))
723                                               return unexpectedCharacter(c);
724                                       fraction = true;
725                                       pushChar();
726                               }
727                       }
728    
729                       return buildLiteral();
730               }
731      /**
732       * @ast method 
733       * @aspect Literals
734       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:878
735       */
736      
737    
738               private Literal parseExponentPart() {
739                       floating = true;
740    
741                       // current char is the exponent specifier char
742                       pushChar();
743    
744                       // exponent sign
745                       if (have(1) && (peek(0) == '+' || peek(0) == '-'))
746                               pushChar();
747    
748                       // while we have at least one more character/digit
749                       while (have(1)) {
750                               char c = peek(0);
751                               switch (c) {
752                                       case '_':
753                                               if (misplacedUnderscore())
754                                                       return syntaxError("misplaced underscore - underscores may only "+
755                                                                       "be used as separators within sequences of valid digits");
756                                               skip(1);
757                                               continue;
758                                       case '-':
759                                       case '+':
760                                               return syntaxError("exponent sign character is only allowed as "+
761                                                               "the first character of the exponent part of a "+
762                                                               "floating point literal");
763                                       case '.':
764                                               return syntaxError("multiple decimal periods are not allowed");
765                                       case 'p':
766                                       case 'P':
767                                               return syntaxError("multiple exponent specifiers are not allowed");
768                                       case 'f':
769                                       case 'F':
770                                               isFloat = true;
771                                       case 'd':
772                                       case 'D':
773                                               if (have(2))
774                                                       return syntaxError("extra digits/characters "+
775                                                                       "after type suffix "+c);
776                                               skip(1);
777                                               continue;
778                               }
779    
780                               // exponent is a signed integer
781                               if (!isDecimalDigit(c))
782                                       return unexpectedCharacter(c);
783                               pushChar();
784                               exponent = true;
785                       }
786    
787                       return buildLiteral();
788               }
789      /**
790       * @ast method 
791       * 
792       */
793      public NumericLiteral() {
794        super();
795    
796    
797      }
798      /**
799       * Initializes the child array to the correct size.
800       * Initializes List and Opt nta children.
801       * @apilevel internal
802       * @ast method
803       * @ast method 
804       * 
805       */
806      public void init$Children() {
807      }
808      /**
809       * @ast method 
810       * 
811       */
812      public NumericLiteral(String p0) {
813        setLITERAL(p0);
814      }
815      /**
816       * @ast method 
817       * 
818       */
819      public NumericLiteral(beaver.Symbol p0) {
820        setLITERAL(p0);
821      }
822      /**
823       * @apilevel low-level
824       * @ast method 
825       * 
826       */
827      protected int numChildren() {
828        return 0;
829      }
830      /**
831       * @apilevel internal
832       * @ast method 
833       * 
834       */
835      public boolean mayHaveRewrite() {
836        return true;
837      }
838      /**
839       * Replaces the lexeme LITERAL.
840       * @param value The new value for the lexeme LITERAL.
841       * @apilevel high-level
842       * @ast method 
843       * 
844       */
845      public void setLITERAL(String value) {
846        tokenString_LITERAL = value;
847      }
848      /**
849       * JastAdd-internal setter for lexeme LITERAL using the Beaver parser.
850       * @apilevel internal
851       * @ast method 
852       * 
853       */
854      public void setLITERAL(beaver.Symbol symbol) {
855        if(symbol.value != null && !(symbol.value instanceof String))
856          throw new UnsupportedOperationException("setLITERAL is only valid for String lexemes");
857        tokenString_LITERAL = (String)symbol.value;
858        LITERALstart = symbol.getStart();
859        LITERALend = symbol.getEnd();
860      }
861      /**
862       * Retrieves the value for the lexeme LITERAL.
863       * @return The value for the lexeme LITERAL.
864       * @apilevel high-level
865       * @ast method 
866       * 
867       */
868      public String getLITERAL() {
869        return tokenString_LITERAL != null ? tokenString_LITERAL : "";
870      }
871      /**
872        * This is a refactored version of Literal.parseLong which supports
873        * binary literals. This version of parseLong is implemented as an
874        * attribute rather than a static method. Perhaps some slight
875        * performance boost could be gained from keeping it static, but with
876        * the loss of declarative- and ReRAGness.
877        *
878        * There exists only a parseLong, and not a parseInteger. Parsing
879        * of regular integer literals works the same, but with stricter
880        * bounds requirements on the resulting parsed value.
881        * @attribute syn
882       * @aspect Literals
883       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:212
884       */
885      public long parseLong() {
886        ASTNode$State state = state();
887        try {
888               switch (getKind()) {
889                       case HEXADECIMAL:
890                               return parseLongHexadecimal();
891                       case OCTAL:
892                               return parseLongOctal();
893                       case BINARY:
894                               return parseLongBinary();
895                       case DECIMAL:
896                       default:
897                               return parseLongDecimal();
898               }
899       }
900        finally {
901        }
902      }
903      /**
904        * Parse a hexadecimal long literal.
905        *
906        * @throws NumberFormatException if the literal is too large.
907        * @attribute syn
908       * @aspect Literals
909       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:231
910       */
911      public long parseLongHexadecimal() {
912        ASTNode$State state = state();
913        try {
914               long val = 0;
915               if (digits.length() > 16) {
916                       for (int i = 0; i < digits.length()-16; i++)
917                               if (digits.charAt(i) != '0')
918                                       throw new NumberFormatException("");
919               }
920               for (int i = 0; i < digits.length(); i++) {
921                       int c = digits.charAt(i);
922                       if (c >= 'a' && c <= 'f')
923                               c = c - 'a' + 10;
924                       else
925                               c = c - '0';
926                       val = val * 16 + c;
927               }
928               return val;
929       }
930        finally {
931        }
932      }
933      /**
934        * Parse an octal long literal.
935        *
936        * @throws NumberFormatException if the literal is too large.
937        * @attribute syn
938       * @aspect Literals
939       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:254
940       */
941      public long parseLongOctal() {
942        ASTNode$State state = state();
943        try {
944               long val = 0;
945               if (digits.length() > 21) {
946                       for (int i = 0; i < digits.length() - 21; i++)
947                               if (i == digits.length() - 21 - 1) {
948                                       if(digits.charAt(i) != '0' && digits.charAt(i) != '1')
949                                               throw new NumberFormatException("");
950                               } else {
951                                       if(digits.charAt(i) != '0')
952                                               throw new NumberFormatException("");
953                               }
954               }
955               for (int i = 0; i < digits.length(); i++) {
956                       int c = digits.charAt(i) - '0';
957                       val = val * 8 + c;
958               }
959               return val;
960       }
961        finally {
962        }
963      }
964      /**
965        * Parse a binary long literal.
966        *
967        * @throws NumberFormatException if the literal is too large.
968        * @attribute syn
969       * @aspect Literals
970       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:278
971       */
972      public long parseLongBinary() {
973        ASTNode$State state = state();
974        try {
975               long val = 0;
976               if (digits.length() > 64) {
977                       for (int i = 0; i < digits.length()-64; i++)
978                               if (digits.charAt(i) != '0')
979                                       throw new NumberFormatException("");
980               }
981               for (int i = 0; i < digits.length(); ++i) {
982                       if (digits.charAt(i) == '1')
983                               val |= 1L << (digits.length()-i-1);
984               }
985               return val;
986       }
987        finally {
988        }
989      }
990      /**
991        * Parse an octal long literal.
992        * @throws NumberFormatException if the literal is too large.
993        * @attribute syn
994       * @aspect Literals
995       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:296
996       */
997      public long parseLongDecimal() {
998        ASTNode$State state = state();
999        try {
1000             long val = 0;
1001             long prev = 0;
1002             for (int i = 0; i < digits.length(); i++) {
1003                     prev = val;
1004                     int c = digits.charAt(i);
1005                     if(c >= '0' && c <= '9')
1006                             c = c - '0';
1007                     else
1008                             throw new NumberFormatException("");
1009                     val = val * 10 + c;
1010                     if (val < prev) {
1011                             boolean negMinValue = i == (digits.length()-1) &&
1012                                     isNegative() && val == Long.MIN_VALUE;
1013                             if (!negMinValue)
1014                                     throw new NumberFormatException("");
1015                     }
1016             }
1017             if (val == Long.MIN_VALUE)
1018                     return val;
1019             if (val < 0)
1020                     throw new NumberFormatException("");
1021             return isNegative() ? -val : val;
1022     }
1023        finally {
1024        }
1025      }
1026      /**
1027      * Utility attribute for literal rewriting.
1028      * Any of the NumericLiteral subclasses have already
1029      * been rewritten and/or parsed, and should not be
1030      * rewritten again.
1031      *
1032      * @return true if this literal is a "raw", not-yet-parsed NumericLiteral
1033      * @attribute syn
1034       * @aspect Literals
1035       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:334
1036       */
1037      public boolean needsRewrite() {
1038        ASTNode$State state = state();
1039        try {  return true;  }
1040        finally {
1041        }
1042      }
1043      /**
1044       * @attribute syn
1045       * @aspect Literals
1046       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:371
1047       */
1048      public boolean isNegative() {
1049        ASTNode$State state = state();
1050        try {  return getLITERAL().charAt(0) == '-';  }
1051        finally {
1052        }
1053      }
1054      /**
1055      * Get the trimmed digits of this literal, excluding
1056      * underscore, prefix and suffix.
1057      * @attribute syn
1058       * @aspect Literals
1059       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:377
1060       */
1061      public String getDigits() {
1062        ASTNode$State state = state();
1063        try {  return digits;  }
1064        finally {
1065        }
1066      }
1067      /**
1068      * The literal kind tells which kind of literal it is;
1069      * it's either a DECIMAL, HEXADECIMAL, OCTAL or BINARY literal.
1070      * @attribute syn
1071       * @aspect Literals
1072       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:395
1073       */
1074      public int getKind() {
1075        ASTNode$State state = state();
1076        try {  return kind;  }
1077        finally {
1078        }
1079      }
1080      /**
1081      * Get the radix of this literal.
1082      * @return 16 (hex), 10 (decimal), 8 (octal) or 2 (binary)
1083      * @attribute syn
1084       * @aspect Literals
1085       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:414
1086       */
1087      public int getRadix() {
1088        ASTNode$State state = state();
1089        try {
1090             switch (kind) {
1091                     case HEXADECIMAL:
1092                             return 16;
1093                     case OCTAL:
1094                             return 8;
1095                     case BINARY:
1096                             return 2;
1097                     case DECIMAL:
1098                     default:
1099                             return 10;
1100             }
1101     }
1102        finally {
1103        }
1104      }
1105      /**
1106      * @return true if the literal is a decimal literal
1107      * @attribute syn
1108       * @aspect Literals
1109       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:431
1110       */
1111      public boolean isDecimal() {
1112        ASTNode$State state = state();
1113        try {  return kind == DECIMAL;  }
1114        finally {
1115        }
1116      }
1117      /**
1118      * @return true if the literal is a hexadecimal literal
1119      * @attribute syn
1120       * @aspect Literals
1121       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:436
1122       */
1123      public boolean isHex() {
1124        ASTNode$State state = state();
1125        try {  return kind == HEXADECIMAL;  }
1126        finally {
1127        }
1128      }
1129      /**
1130      * @return true if the literal is an octal literal
1131      * @attribute syn
1132       * @aspect Literals
1133       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:441
1134       */
1135      public boolean isOctal() {
1136        ASTNode$State state = state();
1137        try {  return kind == OCTAL;  }
1138        finally {
1139        }
1140      }
1141      /**
1142      * @return true if the literal is a binary literal
1143      * @attribute syn
1144       * @aspect Literals
1145       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:446
1146       */
1147      public boolean isBinary() {
1148        ASTNode$State state = state();
1149        try {  return kind == BINARY;  }
1150        finally {
1151        }
1152      }
1153      /**
1154       * @apilevel internal
1155       */
1156      protected boolean type_computed = false;
1157      /**
1158       * @apilevel internal
1159       */
1160      protected TypeDecl type_value;
1161      /**
1162      * The type of a NumericLiteral is undefined.
1163      * The literal must be parsed before it can have a type.
1164      * @attribute syn
1165       * @aspect Literals
1166       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:463
1167       */
1168      @SuppressWarnings({"unchecked", "cast"})
1169      public TypeDecl type() {
1170        if(type_computed) {
1171          return type_value;
1172        }
1173          ASTNode$State state = state();
1174      int num = state.boundariesCrossed;
1175      boolean isFinal = this.is$Final();
1176        type_value = type_compute();
1177      if(isFinal && num == state().boundariesCrossed){ type_computed = true; }
1178            return type_value;
1179      }
1180      /**
1181       * @apilevel internal
1182       */
1183      private TypeDecl type_compute() {  return unknownType();  }
1184      /**
1185       * @apilevel internal
1186       */
1187      public ASTNode rewriteTo() {
1188        // Declared in /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag at line 365
1189        if(needsRewrite()) {
1190          state().duringLiterals++;
1191          ASTNode result = rewriteRule0();
1192          state().duringLiterals--;
1193          return result;
1194        }
1195    
1196        return super.rewriteTo();
1197      }
1198      /**
1199       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/Literals.jrag:365
1200       * @apilevel internal
1201       */  private Literal rewriteRule0() {
1202    {
1203                     return parse();
1204             }  }
1205    }