| 1 | /******************************************************************************* |
|---|
| 2 | Copyright 2009 Sun Microsystems, Inc., |
|---|
| 3 | 4150 Network Circle, Santa Clara, California 95054, U.S.A. |
|---|
| 4 | All rights reserved. |
|---|
| 5 | |
|---|
| 6 | U.S. Government Rights - Commercial software. |
|---|
| 7 | Government users are subject to the Sun Microsystems, Inc. standard |
|---|
| 8 | license agreement and applicable provisions of the FAR and its supplements. |
|---|
| 9 | |
|---|
| 10 | Use is subject to license terms. |
|---|
| 11 | |
|---|
| 12 | This distribution may include materials developed by third parties. |
|---|
| 13 | |
|---|
| 14 | Sun, Sun Microsystems, the Sun logo and Java are trademarks or registered |
|---|
| 15 | trademarks of Sun Microsystems, Inc. in the U.S. and other countries. |
|---|
| 16 | ******************************************************************************/ |
|---|
| 17 | |
|---|
| 18 | /* |
|---|
| 19 | * Definition of Fortress literals. |
|---|
| 20 | */ |
|---|
| 21 | module com.sun.fortress.parser.Literal(Symbol, Spacing); |
|---|
| 22 | |
|---|
| 23 | import Symbol; |
|---|
| 24 | import Spacing; |
|---|
| 25 | |
|---|
| 26 | /* LiteralExpr ::= |
|---|
| 27 | ( w ) |
|---|
| 28 | | NumericLiteralExpr |
|---|
| 29 | | CharLiteralExpr |
|---|
| 30 | | StringLiteralExpr |
|---|
| 31 | */ |
|---|
| 32 | Expr LiteralExpr = |
|---|
| 33 | <VOID> VoidLiteralExpr |
|---|
| 34 | / <NUMERICAL> NumericLiteralExpr |
|---|
| 35 | / <CHAR> CharLiteralExpr |
|---|
| 36 | / <STRING> StringLiteralExpr |
|---|
| 37 | ; |
|---|
| 38 | |
|---|
| 39 | Expr VoidLiteralExpr = |
|---|
| 40 | <FIRST> openparen w closeparen |
|---|
| 41 | { yyValue = ExprFactory.makeVoidLiteralExpr(createSpan(yyStart,yyCount)); }; |
|---|
| 42 | |
|---|
| 43 | transient IntLiteralExpr IntLiteralExpr = |
|---|
| 44 | <FIRST> a1:NumericLiteralExpr &{ (a1 instanceof IntLiteralExpr) } |
|---|
| 45 | { yyValue = (IntLiteralExpr)a1; }; |
|---|
| 46 | |
|---|
| 47 | NumberLiteralExpr NumericLiteralExpr = |
|---|
| 48 | NumericLiteralWithRadix |
|---|
| 49 | / a1:NumericWord a2s:RestNumericWord* &{ Character.isDigit(a1.charAt(0)) } |
|---|
| 50 | { String numeral = a1; |
|---|
| 51 | for (String n: a2s.list()) numeral += n; |
|---|
| 52 | Span span = createSpan(yyStart,yyCount); |
|---|
| 53 | NodeUtil.validNumericLiteral(writer, span, numeral); |
|---|
| 54 | if ( NodeUtil.validIntLiteral(numeral) ) |
|---|
| 55 | yyValue = ExprFactory.makeIntLiteralExpr(span, numeral); |
|---|
| 56 | else yyValue = ExprFactory.makeFloatLiteralExpr(span, numeral); |
|---|
| 57 | }; |
|---|
| 58 | |
|---|
| 59 | private NumberLiteralExpr NumericLiteralWithRadix = |
|---|
| 60 | a1:NumericWord a2s:RestNumericWord* "_" a3:RadixSpecifier |
|---|
| 61 | { String numeral = a1; |
|---|
| 62 | for (String n: a2s.list()) numeral += n; |
|---|
| 63 | Span span = createSpan(yyStart,yyCount); |
|---|
| 64 | NodeUtil.validNumericLiteral(writer, span, numeral, a3); |
|---|
| 65 | numeral += "_"+NodeUtil.radix2Number(a3); |
|---|
| 66 | if ( NodeUtil.validIntLiteral(numeral) ) |
|---|
| 67 | yyValue = ExprFactory.makeIntLiteralExpr(span, numeral); |
|---|
| 68 | else yyValue = ExprFactory.makeFloatLiteralExpr(span, numeral); |
|---|
| 69 | }; |
|---|
| 70 | |
|---|
| 71 | private transient String NumericWord = |
|---|
| 72 | a1s:NumericCharacter+ |
|---|
| 73 | { yyValue = ""; |
|---|
| 74 | for (String n: a1s.list()) yyValue += n; |
|---|
| 75 | }; |
|---|
| 76 | private transient String NumericCharacter = [0-9a-zA-Z]; |
|---|
| 77 | |
|---|
| 78 | private transient String RestNumericWord = |
|---|
| 79 | a1:NumericSeparator a2:NumericWord { yyValue = a1+a2; }; |
|---|
| 80 | |
|---|
| 81 | private transient String NumericSeparator = NumericSpace / "." ; |
|---|
| 82 | private transient String NumericSpace = "'" / "\u202f" ; |
|---|
| 83 | |
|---|
| 84 | private transient String RadixSpecifier = |
|---|
| 85 | a1:DigitString !([a-zA-Z]) &{ NodeUtil.validRadix(writer, createSpan(yyStart,yyCount), a1) } |
|---|
| 86 | / RadixNames ; |
|---|
| 87 | |
|---|
| 88 | private transient String DigitString = [0-9]+; |
|---|
| 89 | |
|---|
| 90 | private transient String RadixNames = |
|---|
| 91 | "SIXTEEN" |
|---|
| 92 | / "FIFTEEN" |
|---|
| 93 | / "FOURTEEN" |
|---|
| 94 | / "THIRTEEN" |
|---|
| 95 | / "TWELVE" |
|---|
| 96 | / "ELEVEN" |
|---|
| 97 | / "TEN" |
|---|
| 98 | / "NINE" |
|---|
| 99 | / "EIGHT" |
|---|
| 100 | / "SEVEN" |
|---|
| 101 | / "SIX" |
|---|
| 102 | / "FIVE" |
|---|
| 103 | / "FOUR" |
|---|
| 104 | / "THREE" |
|---|
| 105 | / "TWO" ; |
|---|
| 106 | |
|---|
| 107 | CharLiteralExpr CharLiteralExpr = |
|---|
| 108 | <FIRST> "'" a1:CharLiteralContent "'" |
|---|
| 109 | { yyValue = ExprFactory.makeCharLiteralExpr(createSpan(yyStart,yyCount), a1); } |
|---|
| 110 | / "`" a1:CharLiteralContent "'" |
|---|
| 111 | { yyValue = ExprFactory.makeCharLiteralExpr(createSpan(yyStart,yyCount), a1); } |
|---|
| 112 | / "\u2018" a1:CharLiteralContent "\u2019" |
|---|
| 113 | { yyValue = ExprFactory.makeCharLiteralExpr(createSpan(yyStart,yyCount), a1); } |
|---|
| 114 | / <ErrorProduction1> "'" a1:CharLiteralContent "\u2019" |
|---|
| 115 | { Span span = createSpan(yyStart,yyCount); |
|---|
| 116 | log(span, "The opening and closing marks of a character literal must match."); |
|---|
| 117 | yyValue = ExprFactory.makeCharLiteralExpr(span, ""); |
|---|
| 118 | } |
|---|
| 119 | / <ErrorProduction2> "`" a1:CharLiteralContent "\u2019" |
|---|
| 120 | { Span span = createSpan(yyStart,yyCount); |
|---|
| 121 | log(span, "The opening and closing marks of a character literal must match."); |
|---|
| 122 | yyValue = ExprFactory.makeCharLiteralExpr(span, ""); |
|---|
| 123 | } |
|---|
| 124 | / <ErrorProduction3> "\u2018" a1:CharLiteralContent "'" |
|---|
| 125 | { Span span = createSpan(yyStart,yyCount); |
|---|
| 126 | log(span, "The opening and closing marks of a character literal must match."); |
|---|
| 127 | yyValue = ExprFactory.makeCharLiteralExpr(span, ""); |
|---|
| 128 | }; |
|---|
| 129 | |
|---|
| 130 | StringLiteralExpr StringLiteralExpr = |
|---|
| 131 | <FIRST> ["] a1:StringLiteralContent* ["] |
|---|
| 132 | { String str = ""; |
|---|
| 133 | for (String c : (List<String>)a1.list()) str = str.concat(c); |
|---|
| 134 | yyValue = ExprFactory.makeStringLiteralExpr(createSpan(yyStart,yyCount), str); |
|---|
| 135 | } |
|---|
| 136 | / "\u201c" a1:StringLiteralContent* "\u201d" |
|---|
| 137 | { String str = ""; |
|---|
| 138 | for (String c : (List<String>)a1.list()) str = str.concat(c); |
|---|
| 139 | yyValue = ExprFactory.makeStringLiteralExpr(createSpan(yyStart,yyCount), str); |
|---|
| 140 | } |
|---|
| 141 | / <ErrorProduction1> ["] a1:StringLiteralContent* "\u201d" |
|---|
| 142 | { Span span = createSpan(yyStart,yyCount); |
|---|
| 143 | log(span, "The opening and closing marks of a string literal must match."); |
|---|
| 144 | yyValue = ExprFactory.makeStringLiteralExpr(span, ""); |
|---|
| 145 | } |
|---|
| 146 | / <ErrorProduction2> "\u201c" a1:StringLiteralContent* ["] |
|---|
| 147 | { Span span = createSpan(yyStart,yyCount); |
|---|
| 148 | log(span, "The opening and closing marks of a string literal must match."); |
|---|
| 149 | yyValue = ExprFactory.makeStringLiteralExpr(span, ""); |
|---|
| 150 | }; |
|---|
| 151 | private String StringLiteralContent = |
|---|
| 152 | EscapeSequence |
|---|
| 153 | / a1:(!InvalidStringLiteralContent _) { yyValue = String.valueOf(a1); }; |
|---|
| 154 | |
|---|
| 155 | private void InvalidStringLiteralContent = |
|---|
| 156 | void:["\u201c\u201d] |
|---|
| 157 | / a1:[\\] |
|---|
| 158 | { log(createSpan(yyStart,yyCount), "Invalid string literal content: " + a1); } |
|---|
| 159 | / a1:[\n\f\r\u0009\u000b\u001c\u001d\u001e\u001f\u2028\u2029] |
|---|
| 160 | { log(createSpan(yyStart,yyCount), "Invalid string literal content: " + a1); } |
|---|
| 161 | / c:_ &{ Character.getType(c) == Character.CONTROL } |
|---|
| 162 | { log(createSpan(yyStart,yyCount), "Invalid string literal content: " + c); }; |
|---|
| 163 | |
|---|
| 164 | private String EscapeSequence = |
|---|
| 165 | '\\' a1:[btnfr"\\] |
|---|
| 166 | { switch (a1) { |
|---|
| 167 | case 'b': { yyValue = "\b"; break; } |
|---|
| 168 | case 't': { yyValue = "\t"; break; } |
|---|
| 169 | case 'n': { yyValue = "\n"; break; } |
|---|
| 170 | case 'f': { yyValue = "\f"; break; } |
|---|
| 171 | case 'r': { yyValue = "\r"; break; } |
|---|
| 172 | case '"': { yyValue = "\""; break; } |
|---|
| 173 | case '\\': { yyValue = "\\"; break; } |
|---|
| 174 | default: { yyValue = ""; } |
|---|
| 175 | } |
|---|
| 176 | } |
|---|
| 177 | / '\\' a1:[\u201c] { yyValue = "\u201c"; } |
|---|
| 178 | / '\\' a1:[\u201d] { yyValue = "\u201d"; }; |
|---|
| 179 | |
|---|
| 180 | private String CharLiteralContent = |
|---|
| 181 | EscapeSequence |
|---|
| 182 | / a1:(!InvalidCharLiteralContent _) { yyValue = String.valueOf(a1); }; |
|---|
| 183 | |
|---|
| 184 | private String InvalidCharLiteralContent = |
|---|
| 185 | a1:[\\\n\f\r\u0009\u000b\u001c\u001d\u001e\u001f"\u201c\u201d\u2028\u2029] |
|---|
| 186 | { log(createSpan(yyStart,yyCount), "Invalid character literal: " + a1); |
|---|
| 187 | yyValue = ""; |
|---|
| 188 | } |
|---|
| 189 | / c:_ &{ Character.getType(c) == Character.CONTROL } |
|---|
| 190 | { log(createSpan(yyStart,yyCount), "Invalid character literal: " + c); |
|---|
| 191 | yyValue = ""; |
|---|
| 192 | }; |
|---|