You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Parser.java 44KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365
  1. /*
  2. * Javassist, a Java-bytecode translator toolkit.
  3. * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
  4. *
  5. * The contents of this file are subject to the Mozilla Public License Version
  6. * 1.1 (the "License"); you may not use this file except in compliance with
  7. * the License. Alternatively, the contents of this file may be used under
  8. * the terms of the GNU Lesser General Public License Version 2.1 or later,
  9. * or the Apache License Version 2.0.
  10. *
  11. * Software distributed under the License is distributed on an "AS IS" basis,
  12. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  13. * for the specific language governing rights and limitations under the
  14. * License.
  15. */
  16. package javassist.compiler;
  17. import javassist.compiler.ast.ASTList;
  18. import javassist.compiler.ast.ASTree;
  19. import javassist.compiler.ast.ArrayInit;
  20. import javassist.compiler.ast.AssignExpr;
  21. import javassist.compiler.ast.BinExpr;
  22. import javassist.compiler.ast.CallExpr;
  23. import javassist.compiler.ast.CastExpr;
  24. import javassist.compiler.ast.CondExpr;
  25. import javassist.compiler.ast.Declarator;
  26. import javassist.compiler.ast.DoubleConst;
  27. import javassist.compiler.ast.Expr;
  28. import javassist.compiler.ast.FieldDecl;
  29. import javassist.compiler.ast.InstanceOfExpr;
  30. import javassist.compiler.ast.IntConst;
  31. import javassist.compiler.ast.Keyword;
  32. import javassist.compiler.ast.Member;
  33. import javassist.compiler.ast.MethodDecl;
  34. import javassist.compiler.ast.NewExpr;
  35. import javassist.compiler.ast.Pair;
  36. import javassist.compiler.ast.Stmnt;
  37. import javassist.compiler.ast.StringL;
  38. import javassist.compiler.ast.Symbol;
  39. import javassist.compiler.ast.Variable;
  40. public final class Parser implements TokenId {
  41. private Lex lex;
  42. public Parser(Lex lex) {
  43. this.lex = lex;
  44. }
  45. public boolean hasMore() { return lex.lookAhead() >= 0; }
  46. /* member.declaration
  47. * : method.declaration | field.declaration
  48. */
  49. public ASTList parseMember(SymbolTable tbl) throws CompileError {
  50. ASTList mem = parseMember1(tbl);
  51. if (mem instanceof MethodDecl)
  52. return parseMethod2(tbl, (MethodDecl)mem);
  53. return mem;
  54. }
  55. /* A method body is not parsed.
  56. */
  57. public ASTList parseMember1(SymbolTable tbl) throws CompileError {
  58. ASTList mods = parseMemberMods();
  59. Declarator d;
  60. boolean isConstructor = false;
  61. if (lex.lookAhead() == Identifier && lex.lookAhead(1) == '(') {
  62. d = new Declarator(VOID, 0, lex.getLineNumber());
  63. isConstructor = true;
  64. }
  65. else
  66. d = parseFormalType(tbl);
  67. if (lex.get() != Identifier)
  68. throw new SyntaxError(lex);
  69. String name;
  70. if (isConstructor)
  71. name = MethodDecl.initName;
  72. else
  73. name = lex.getString();
  74. d.setVariable(new Symbol(name, lex.getLineNumber()));
  75. if (isConstructor || lex.lookAhead() == '(')
  76. return parseMethod1(tbl, isConstructor, mods, d);
  77. return parseField(tbl, mods, d);
  78. }
  79. /* field.declaration
  80. * : member.modifiers
  81. * formal.type Identifier
  82. * [ "=" expression ] ";"
  83. */
  84. private FieldDecl parseField(SymbolTable tbl, ASTList mods,
  85. Declarator d) throws CompileError
  86. {
  87. ASTree expr = null;
  88. if (lex.lookAhead() == '=') {
  89. lex.get();
  90. expr = parseExpression(tbl);
  91. }
  92. int c = lex.get();
  93. if (c == ';')
  94. return new FieldDecl(mods, new ASTList(d, new ASTList(expr, lex.getLineNumber()), lex.getLineNumber()), lex.getLineNumber());
  95. else if (c == ',')
  96. throw new CompileError(
  97. "only one field can be declared in one declaration", lex);
  98. else
  99. throw new SyntaxError(lex);
  100. }
  101. /* method.declaration
  102. * : member.modifiers
  103. * [ formal.type ]
  104. * Identifier "(" [ formal.parameter ( "," formal.parameter )* ] ")"
  105. * array.dimension
  106. * [ THROWS class.type ( "," class.type ) ]
  107. * ( block.statement | ";" )
  108. *
  109. * Note that a method body is not parsed.
  110. */
  111. private MethodDecl parseMethod1(SymbolTable tbl, boolean isConstructor,
  112. ASTList mods, Declarator d)
  113. throws CompileError
  114. {
  115. if (lex.get() != '(')
  116. throw new SyntaxError(lex);
  117. ASTList parms = null;
  118. if (lex.lookAhead() != ')')
  119. while (true) {
  120. parms = ASTList.append(parms, parseFormalParam(tbl), lex.getLineNumber());
  121. int t = lex.lookAhead();
  122. if (t == ',')
  123. lex.get();
  124. else if (t == ')')
  125. break;
  126. }
  127. lex.get(); // ')'
  128. d.addArrayDim(parseArrayDimension());
  129. if (isConstructor && d.getArrayDim() > 0)
  130. throw new SyntaxError(lex);
  131. ASTList throwsList = null;
  132. if (lex.lookAhead() == THROWS) {
  133. lex.get();
  134. while (true) {
  135. throwsList = ASTList.append(throwsList, parseClassType(tbl), lex.getLineNumber());
  136. if (lex.lookAhead() == ',')
  137. lex.get();
  138. else
  139. break;
  140. }
  141. }
  142. return new MethodDecl(mods, new ASTList(d,
  143. ASTList.make(parms, throwsList, null, lex.getLineNumber()), lex.getLineNumber()), lex.getLineNumber());
  144. }
  145. /* Parses a method body.
  146. */
  147. public MethodDecl parseMethod2(SymbolTable tbl, MethodDecl md)
  148. throws CompileError
  149. {
  150. Stmnt body = null;
  151. if (lex.lookAhead() == ';')
  152. lex.get();
  153. else {
  154. body = parseBlock(tbl);
  155. if (body == null)
  156. body = new Stmnt(BLOCK, lex.getLineNumber());
  157. }
  158. md.sublist(4).setHead(body);
  159. return md;
  160. }
  161. /* member.modifiers
  162. * : ( FINAL | SYNCHRONIZED | ABSTRACT
  163. * | PUBLIC | PROTECTED | PRIVATE | STATIC
  164. * | VOLATILE | TRANSIENT | STRICT )*
  165. */
  166. private ASTList parseMemberMods() {
  167. int t;
  168. ASTList list = null;
  169. while (true) {
  170. t = lex.lookAhead();
  171. if (t == ABSTRACT || t == FINAL || t == PUBLIC || t == PROTECTED
  172. || t == PRIVATE || t == SYNCHRONIZED || t == STATIC
  173. || t == VOLATILE || t == TRANSIENT || t == STRICT)
  174. list = new ASTList(new Keyword(lex.get(), lex.getLineNumber()), list, lex.getLineNumber());
  175. else
  176. break;
  177. }
  178. return list;
  179. }
  180. /* formal.type : ( build-in-type | class.type ) array.dimension
  181. */
  182. private Declarator parseFormalType(SymbolTable tbl) throws CompileError {
  183. int t = lex.lookAhead();
  184. if (isBuiltinType(t) || t == VOID) {
  185. lex.get(); // primitive type
  186. int dim = parseArrayDimension();
  187. return new Declarator(t, dim, lex.getLineNumber());
  188. }
  189. ASTList name = parseClassType(tbl);
  190. int dim = parseArrayDimension();
  191. return new Declarator(name, dim, lex.getLineNumber());
  192. }
  193. private static boolean isBuiltinType(int t) {
  194. return (t == BOOLEAN || t == BYTE || t == CHAR || t == SHORT
  195. || t == INT || t == LONG || t == FLOAT || t == DOUBLE);
  196. }
  197. /* formal.parameter : formal.type Identifier array.dimension
  198. */
  199. private Declarator parseFormalParam(SymbolTable tbl)
  200. throws CompileError
  201. {
  202. Declarator d = parseFormalType(tbl);
  203. if (lex.get() != Identifier)
  204. throw new SyntaxError(lex);
  205. String name = lex.getString();
  206. d.setVariable(new Symbol(name, lex.getLineNumber()));
  207. d.addArrayDim(parseArrayDimension());
  208. tbl.append(name, d);
  209. return d;
  210. }
  211. /* statement : [ label ":" ]* labeled.statement
  212. *
  213. * labeled.statement
  214. * : block.statement
  215. * | if.statement
  216. * | while.statement
  217. * | do.statement
  218. * | for.statement
  219. * | switch.statement
  220. * | try.statement
  221. * | return.statement
  222. * | thorw.statement
  223. * | break.statement
  224. * | continue.statement
  225. * | declaration.or.expression
  226. * | ";"
  227. *
  228. * This method may return null (empty statement).
  229. */
  230. public Stmnt parseStatement(SymbolTable tbl)
  231. throws CompileError
  232. {
  233. int t = lex.lookAhead();
  234. if (t == '{')
  235. return parseBlock(tbl);
  236. else if (t == ';') {
  237. lex.get();
  238. return new Stmnt(BLOCK, lex.getLineNumber()); // empty statement
  239. }
  240. else if (t == Identifier && lex.lookAhead(1) == ':') {
  241. lex.get(); // Identifier
  242. String label = lex.getString();
  243. lex.get(); // ':'
  244. return Stmnt.make(LABEL, new Symbol(label, lex.getLineNumber()), parseStatement(tbl), lex.getLineNumber());
  245. }
  246. else if (t == IF)
  247. return parseIf(tbl);
  248. else if (t == WHILE)
  249. return parseWhile(tbl);
  250. else if (t == DO)
  251. return parseDo(tbl);
  252. else if (t == FOR)
  253. return parseFor(tbl);
  254. else if (t == TRY)
  255. return parseTry(tbl);
  256. else if (t == SWITCH)
  257. return parseSwitch(tbl);
  258. else if (t == SYNCHRONIZED)
  259. return parseSynchronized(tbl);
  260. else if (t == RETURN)
  261. return parseReturn(tbl);
  262. else if (t == THROW)
  263. return parseThrow(tbl);
  264. else if (t == BREAK)
  265. return parseBreak(tbl);
  266. else if (t == CONTINUE)
  267. return parseContinue(tbl);
  268. else
  269. return parseDeclarationOrExpression(tbl, false);
  270. }
  271. /* block.statement : "{" statement* "}"
  272. */
  273. private Stmnt parseBlock(SymbolTable tbl) throws CompileError {
  274. int blockLineNumber = lex.getLineNumber();
  275. if (lex.get() != '{')
  276. throw new SyntaxError(lex);
  277. Stmnt body = null;
  278. SymbolTable tbl2 = new SymbolTable(tbl);
  279. while (lex.lookAhead() != '}') {
  280. int lineNumber = lex.getLineNumber();
  281. Stmnt s = parseStatement(tbl2);
  282. if (s != null)
  283. body = (Stmnt)ASTList.concat(body, new Stmnt(BLOCK, s, lineNumber));
  284. }
  285. lex.get(); // '}'
  286. if (body == null)
  287. return new Stmnt(BLOCK, blockLineNumber); // empty block
  288. return body;
  289. }
  290. /* if.statement : IF "(" expression ")" statement
  291. * [ ELSE statement ]
  292. */
  293. private Stmnt parseIf(SymbolTable tbl) throws CompileError {
  294. int t = lex.get(); // IF
  295. ASTree expr = parseParExpression(tbl);
  296. int exprLineNum = lex.getLineNumber();
  297. Stmnt thenp = parseStatement(tbl);
  298. int thenLineNum = lex.getLineNumber();
  299. Stmnt elsep;
  300. if (lex.lookAhead() == ELSE) {
  301. lex.get();
  302. elsep = parseStatement(tbl);
  303. }
  304. else
  305. elsep = null;
  306. return new Stmnt(t, expr, new ASTList(thenp, new ASTList(elsep, lex.getLineNumber()), thenLineNum), exprLineNum);
  307. }
  308. /* while.statement : WHILE "(" expression ")" statement
  309. */
  310. private Stmnt parseWhile(SymbolTable tbl)
  311. throws CompileError
  312. {
  313. int t = lex.get(); // WHILE
  314. ASTree expr = parseParExpression(tbl);
  315. int lineNumber = lex.getLineNumber();
  316. Stmnt body = parseStatement(tbl);
  317. return new Stmnt(t, expr, body, lineNumber);
  318. }
  319. /* do.statement : DO statement WHILE "(" expression ")" ";"
  320. */
  321. private Stmnt parseDo(SymbolTable tbl) throws CompileError {
  322. int t = lex.get(); // DO
  323. Stmnt body = parseStatement(tbl);
  324. if (lex.get() != WHILE || lex.get() != '(')
  325. throw new SyntaxError(lex);
  326. ASTree expr = parseExpression(tbl);
  327. if (lex.get() != ')' || lex.get() != ';')
  328. throw new SyntaxError(lex);
  329. return new Stmnt(t, expr, body, lex.getLineNumber());
  330. }
  331. /* for.statement : FOR "(" decl.or.expr expression ";" expression ")"
  332. * statement
  333. */
  334. private Stmnt parseFor(SymbolTable tbl) throws CompileError {
  335. Stmnt expr1, expr3;
  336. ASTree expr2;
  337. int t = lex.get(); // FOR
  338. SymbolTable tbl2 = new SymbolTable(tbl);
  339. if (lex.get() != '(')
  340. throw new SyntaxError(lex);
  341. int expr1LineNumber = lex.getLineNumber();
  342. if (lex.lookAhead() == ';') {
  343. lex.get();
  344. expr1 = null;
  345. }
  346. else
  347. expr1 = parseDeclarationOrExpression(tbl2, true);
  348. int expr2LineNumber = lex.getLineNumber();
  349. if (lex.lookAhead() == ';')
  350. expr2 = null;
  351. else
  352. expr2 = parseExpression(tbl2);
  353. if (lex.get() != ';')
  354. throw new CompileError("; is missing", lex);
  355. int expr3LineNumber = lex.getLineNumber();
  356. if (lex.lookAhead() == ')')
  357. expr3 = null;
  358. else
  359. expr3 = parseExprList(tbl2);
  360. if (lex.get() != ')')
  361. throw new CompileError(") is missing", lex);
  362. Stmnt body = parseStatement(tbl2);
  363. return new Stmnt(t, expr1, new ASTList(expr2,
  364. new ASTList(expr3, body, expr3LineNumber), expr2LineNumber), expr1LineNumber);
  365. }
  366. /* switch.statement : SWITCH "(" expression ")" "{" switch.block "}"
  367. *
  368. * swtich.block : ( switch.label statement* )*
  369. *
  370. * swtich.label : DEFAULT ":"
  371. * | CASE const.expression ":"
  372. */
  373. private Stmnt parseSwitch(SymbolTable tbl) throws CompileError {
  374. int t = lex.get(); // SWITCH
  375. ASTree expr = parseParExpression(tbl);
  376. Stmnt body = parseSwitchBlock(tbl);
  377. return new Stmnt(t, expr, body, lex.getLineNumber());
  378. }
  379. private Stmnt parseSwitchBlock(SymbolTable tbl) throws CompileError {
  380. if (lex.get() != '{')
  381. throw new SyntaxError(lex);
  382. SymbolTable tbl2 = new SymbolTable(tbl);
  383. Stmnt s = parseStmntOrCase(tbl2);
  384. if (s == null)
  385. throw new CompileError("empty switch block", lex);
  386. int op = s.getOperator();
  387. if (op != CASE && op != DEFAULT)
  388. throw new CompileError("no case or default in a switch block",
  389. lex);
  390. Stmnt body = new Stmnt(BLOCK, s, lex.getLineNumber());
  391. while (lex.lookAhead() != '}') {
  392. Stmnt s2 = parseStmntOrCase(tbl2);
  393. if (s2 != null) {
  394. int op2 = s2.getOperator();
  395. if (op2 == CASE || op2 == DEFAULT) {
  396. body = (Stmnt)ASTList.concat(body, new Stmnt(BLOCK, s2, lex.getLineNumber()));
  397. s = s2;
  398. }
  399. else
  400. s = (Stmnt)ASTList.concat(s, new Stmnt(BLOCK, s2, lex.getLineNumber()));
  401. }
  402. }
  403. lex.get(); // '}'
  404. return body;
  405. }
  406. private Stmnt parseStmntOrCase(SymbolTable tbl) throws CompileError {
  407. int t = lex.lookAhead();
  408. if (t != CASE && t != DEFAULT)
  409. return parseStatement(tbl);
  410. lex.get();
  411. Stmnt s;
  412. if (t == CASE)
  413. s = new Stmnt(t, parseExpression(tbl), lex.getLineNumber());
  414. else
  415. s = new Stmnt(DEFAULT, lex.getLineNumber());
  416. if (lex.get() != ':')
  417. throw new CompileError(": is missing", lex);
  418. return s;
  419. }
  420. /* synchronized.statement :
  421. * SYNCHRONIZED "(" expression ")" block.statement
  422. */
  423. private Stmnt parseSynchronized(SymbolTable tbl) throws CompileError {
  424. int t = lex.get(); // SYNCHRONIZED
  425. if (lex.get() != '(')
  426. throw new SyntaxError(lex);
  427. ASTree expr = parseExpression(tbl);
  428. if (lex.get() != ')')
  429. throw new SyntaxError(lex);
  430. Stmnt body = parseBlock(tbl);
  431. return new Stmnt(t, expr, body, lex.getLineNumber());
  432. }
  433. /* try.statement
  434. * : TRY block.statement
  435. * [ CATCH "(" class.type Identifier ")" block.statement ]*
  436. * [ FINALLY block.statement ]*
  437. */
  438. private Stmnt parseTry(SymbolTable tbl) throws CompileError {
  439. lex.get(); // TRY
  440. Stmnt block = parseBlock(tbl);
  441. ASTList catchList = null;
  442. while (lex.lookAhead() == CATCH) {
  443. lex.get(); // CATCH
  444. if (lex.get() != '(')
  445. throw new SyntaxError(lex);
  446. SymbolTable tbl2 = new SymbolTable(tbl);
  447. Declarator d = parseFormalParam(tbl2);
  448. if (d.getArrayDim() > 0 || d.getType() != CLASS)
  449. throw new SyntaxError(lex);
  450. if (lex.get() != ')')
  451. throw new SyntaxError(lex);
  452. Stmnt b = parseBlock(tbl2);
  453. catchList = ASTList.append(catchList, new Pair(d, b), lex.getLineNumber());
  454. }
  455. Stmnt finallyBlock = null;
  456. if (lex.lookAhead() == FINALLY) {
  457. lex.get(); // FINALLY
  458. finallyBlock = parseBlock(tbl);
  459. }
  460. return Stmnt.make(TRY, block, catchList, finallyBlock, lex.getLineNumber());
  461. }
  462. /* return.statement : RETURN [ expression ] ";"
  463. */
  464. private Stmnt parseReturn(SymbolTable tbl) throws CompileError {
  465. int t = lex.get(); // RETURN
  466. Stmnt s = new Stmnt(t, lex.getLineNumber());
  467. if (lex.lookAhead() != ';')
  468. s.setLeft(parseExpression(tbl));
  469. if (lex.get() != ';')
  470. throw new CompileError("; is missing", lex);
  471. return s;
  472. }
  473. /* throw.statement : THROW expression ";"
  474. */
  475. private Stmnt parseThrow(SymbolTable tbl) throws CompileError {
  476. int t = lex.get(); // THROW
  477. ASTree expr = parseExpression(tbl);
  478. if (lex.get() != ';')
  479. throw new CompileError("; is missing", lex);
  480. return new Stmnt(t, expr, lex.getLineNumber());
  481. }
  482. /* break.statement : BREAK [ Identifier ] ";"
  483. */
  484. private Stmnt parseBreak(SymbolTable tbl)
  485. throws CompileError
  486. {
  487. return parseContinue(tbl);
  488. }
  489. /* continue.statement : CONTINUE [ Identifier ] ";"
  490. */
  491. private Stmnt parseContinue(SymbolTable tbl)
  492. throws CompileError
  493. {
  494. int t = lex.get(); // CONTINUE
  495. Stmnt s = new Stmnt(t, lex.getLineNumber());
  496. int t2 = lex.get();
  497. if (t2 == Identifier) {
  498. s.setLeft(new Symbol(lex.getString(), lex.getLineNumber()));
  499. t2 = lex.get();
  500. }
  501. if (t2 != ';')
  502. throw new CompileError("; is missing", lex);
  503. return s;
  504. }
  505. /* declaration.or.expression
  506. * : [ FINAL ] built-in-type array.dimension declarators
  507. * | [ FINAL ] class.type array.dimension declarators
  508. * | expression ';'
  509. * | expr.list ';' if exprList is true
  510. *
  511. * Note: FINAL is currently ignored. This must be fixed
  512. * in future.
  513. */
  514. private Stmnt parseDeclarationOrExpression(SymbolTable tbl,
  515. boolean exprList)
  516. throws CompileError
  517. {
  518. int t = lex.lookAhead();
  519. while (t == FINAL) {
  520. lex.get();
  521. t = lex.lookAhead();
  522. }
  523. if (isBuiltinType(t)) {
  524. t = lex.get();
  525. int dim = parseArrayDimension();
  526. return parseDeclarators(tbl, new Declarator(t, dim, lex.getLineNumber()));
  527. }
  528. else if (t == Identifier) {
  529. int i = nextIsClassType(0);
  530. if (i >= 0)
  531. if (lex.lookAhead(i) == Identifier) {
  532. ASTList name = parseClassType(tbl);
  533. int dim = parseArrayDimension();
  534. return parseDeclarators(tbl, new Declarator(name, dim, lex.getLineNumber()));
  535. }
  536. }
  537. Stmnt expr;
  538. if (exprList)
  539. expr = parseExprList(tbl);
  540. else
  541. expr = new Stmnt(EXPR, parseExpression(tbl), lex.getLineNumber());
  542. if (lex.get() != ';')
  543. throw new CompileError("; is missing", lex);
  544. return expr;
  545. }
  546. /* expr.list : ( expression ',')* expression
  547. */
  548. private Stmnt parseExprList(SymbolTable tbl) throws CompileError {
  549. Stmnt expr = null;
  550. for (;;) {
  551. Stmnt e = new Stmnt(EXPR, parseExpression(tbl), lex.getLineNumber());
  552. expr = (Stmnt)ASTList.concat(expr, new Stmnt(BLOCK, e, lex.getLineNumber()));
  553. if (lex.lookAhead() == ',')
  554. lex.get();
  555. else
  556. return expr;
  557. }
  558. }
  559. /* declarators : declarator [ ',' declarator ]* ';'
  560. */
  561. private Stmnt parseDeclarators(SymbolTable tbl, Declarator d)
  562. throws CompileError
  563. {
  564. Stmnt decl = null;
  565. for (;;) {
  566. decl = (Stmnt)ASTList.concat(decl,
  567. new Stmnt(DECL, parseDeclarator(tbl, d), lex.getLineNumber()));
  568. int t = lex.get();
  569. if (t == ';')
  570. return decl;
  571. else if (t != ',')
  572. throw new CompileError("; is missing", lex);
  573. }
  574. }
  575. /* declarator : Identifier array.dimension [ '=' initializer ]
  576. */
  577. private Declarator parseDeclarator(SymbolTable tbl, Declarator d)
  578. throws CompileError
  579. {
  580. if (lex.get() != Identifier || d.getType() == VOID)
  581. throw new SyntaxError(lex);
  582. String name = lex.getString();
  583. Symbol symbol = new Symbol(name, lex.getLineNumber());
  584. int dim = parseArrayDimension();
  585. ASTree init = null;
  586. if (lex.lookAhead() == '=') {
  587. lex.get();
  588. init = parseInitializer(tbl);
  589. }
  590. Declarator decl = d.make(symbol, dim, init, lex.getLineNumber());
  591. tbl.append(name, decl);
  592. return decl;
  593. }
  594. /* initializer : expression | array.initializer
  595. */
  596. private ASTree parseInitializer(SymbolTable tbl) throws CompileError {
  597. if (lex.lookAhead() == '{')
  598. return parseArrayInitializer(tbl);
  599. return parseExpression(tbl);
  600. }
  601. /* array.initializer :
  602. * '{' (( array.initializer | expression ) ',')* '}'
  603. */
  604. private ArrayInit parseArrayInitializer(SymbolTable tbl)
  605. throws CompileError
  606. {
  607. lex.get(); // '{'
  608. if(lex.lookAhead() == '}'){
  609. lex.get();
  610. return new ArrayInit(null, lex.getLineNumber());
  611. }
  612. ASTree expr = parseExpression(tbl);
  613. ArrayInit init = new ArrayInit(expr, lex.getLineNumber());
  614. while (lex.lookAhead() == ',') {
  615. lex.get();
  616. expr = parseExpression(tbl);
  617. ASTList.append(init, expr, lex.getLineNumber());
  618. }
  619. if (lex.get() != '}')
  620. throw new SyntaxError(lex);
  621. return init;
  622. }
  623. /* par.expression : '(' expression ')'
  624. */
  625. private ASTree parseParExpression(SymbolTable tbl) throws CompileError {
  626. if (lex.get() != '(')
  627. throw new SyntaxError(lex);
  628. ASTree expr = parseExpression(tbl);
  629. if (lex.get() != ')')
  630. throw new SyntaxError(lex);
  631. return expr;
  632. }
  633. /* expression : conditional.expr
  634. * | conditional.expr assign.op expression (right-to-left)
  635. */
  636. public ASTree parseExpression(SymbolTable tbl) throws CompileError {
  637. ASTree left = parseConditionalExpr(tbl);
  638. if (!isAssignOp(lex.lookAhead()))
  639. return left;
  640. int t = lex.get();
  641. ASTree right = parseExpression(tbl);
  642. return AssignExpr.makeAssign(t, left, right, lex.getLineNumber());
  643. }
  644. private static boolean isAssignOp(int t) {
  645. return t == '=' || t == MOD_E || t == AND_E
  646. || t == MUL_E || t == PLUS_E || t == MINUS_E || t == DIV_E
  647. || t == EXOR_E || t == OR_E || t == LSHIFT_E
  648. || t == RSHIFT_E || t == ARSHIFT_E;
  649. }
  650. /* conditional.expr (right-to-left)
  651. * : logical.or.expr [ '?' expression ':' conditional.expr ]
  652. */
  653. private ASTree parseConditionalExpr(SymbolTable tbl) throws CompileError {
  654. ASTree cond = parseBinaryExpr(tbl);
  655. if (lex.lookAhead() == '?') {
  656. lex.get();
  657. ASTree thenExpr = parseExpression(tbl);
  658. if (lex.get() != ':')
  659. throw new CompileError(": is missing", lex);
  660. ASTree elseExpr = parseExpression(tbl);
  661. return new CondExpr(cond, thenExpr, elseExpr, lex.getLineNumber());
  662. }
  663. return cond;
  664. }
  665. /* logical.or.expr 10 (operator precedence)
  666. * : logical.and.expr
  667. * | logical.or.expr OROR logical.and.expr left-to-right
  668. *
  669. * logical.and.expr 9
  670. * : inclusive.or.expr
  671. * | logical.and.expr ANDAND inclusive.or.expr
  672. *
  673. * inclusive.or.expr 8
  674. * : exclusive.or.expr
  675. * | inclusive.or.expr "|" exclusive.or.expr
  676. *
  677. * exclusive.or.expr 7
  678. * : and.expr
  679. * | exclusive.or.expr "^" and.expr
  680. *
  681. * and.expr 6
  682. * : equality.expr
  683. * | and.expr "&" equality.expr
  684. *
  685. * equality.expr 5
  686. * : relational.expr
  687. * | equality.expr (EQ | NEQ) relational.expr
  688. *
  689. * relational.expr 4
  690. * : shift.expr
  691. * | relational.expr (LE | GE | "<" | ">") shift.expr
  692. * | relational.expr INSTANCEOF class.type ("[" "]")*
  693. *
  694. * shift.expr 3
  695. * : additive.expr
  696. * | shift.expr (LSHIFT | RSHIFT | ARSHIFT) additive.expr
  697. *
  698. * additive.expr 2
  699. * : multiply.expr
  700. * | additive.expr ("+" | "-") multiply.expr
  701. *
  702. * multiply.expr 1
  703. * : unary.expr
  704. * | multiply.expr ("*" | "/" | "%") unary.expr
  705. */
  706. private ASTree parseBinaryExpr(SymbolTable tbl) throws CompileError {
  707. ASTree expr = parseUnaryExpr(tbl);
  708. for (;;) {
  709. int t = lex.lookAhead();
  710. int p = getOpPrecedence(t);
  711. if (p == 0)
  712. return expr;
  713. expr = binaryExpr2(tbl, expr, p);
  714. }
  715. }
  716. private ASTree parseInstanceOf(SymbolTable tbl, ASTree expr)
  717. throws CompileError
  718. {
  719. int t = lex.lookAhead();
  720. if (isBuiltinType(t)) {
  721. lex.get(); // primitive type
  722. int dim = parseArrayDimension();
  723. return new InstanceOfExpr(t, dim, expr, lex.getLineNumber());
  724. }
  725. ASTList name = parseClassType(tbl);
  726. int dim = parseArrayDimension();
  727. return new InstanceOfExpr(name, dim, expr, lex.getLineNumber());
  728. }
  729. private ASTree binaryExpr2(SymbolTable tbl, ASTree expr, int prec)
  730. throws CompileError
  731. {
  732. int t = lex.get();
  733. if (t == INSTANCEOF)
  734. return parseInstanceOf(tbl, expr);
  735. ASTree expr2 = parseUnaryExpr(tbl);
  736. for (;;) {
  737. int t2 = lex.lookAhead();
  738. int p2 = getOpPrecedence(t2);
  739. if (p2 != 0 && prec > p2)
  740. expr2 = binaryExpr2(tbl, expr2, p2);
  741. else
  742. return BinExpr.makeBin(t, expr, expr2, lex.getLineNumber());
  743. }
  744. }
  745. // !"#$%&'( )*+,-./0 12345678 9:;<=>?
  746. private static final int[] binaryOpPrecedence
  747. = { 0, 0, 0, 0, 1, 6, 0, 0,
  748. 0, 1, 2, 0, 2, 0, 1, 0,
  749. 0, 0, 0, 0, 0, 0, 0, 0,
  750. 0, 0, 0, 4, 0, 4, 0 };
  751. private int getOpPrecedence(int c) {
  752. if ('!' <= c && c <= '?')
  753. return binaryOpPrecedence[c - '!'];
  754. else if (c == '^')
  755. return 7;
  756. else if (c == '|')
  757. return 8;
  758. else if (c == ANDAND)
  759. return 9;
  760. else if (c == OROR)
  761. return 10;
  762. else if (c == EQ || c == NEQ)
  763. return 5;
  764. else if (c == LE || c == GE || c == INSTANCEOF)
  765. return 4;
  766. else if (c == LSHIFT || c == RSHIFT || c == ARSHIFT)
  767. return 3;
  768. else
  769. return 0; // not a binary operator
  770. }
  771. /* unary.expr : "++"|"--" unary.expr
  772. | "+"|"-" unary.expr
  773. | "!"|"~" unary.expr
  774. | cast.expr
  775. | postfix.expr
  776. unary.expr.not.plus.minus is a unary expression starting without
  777. "+", "-", "++", or "--".
  778. */
  779. private ASTree parseUnaryExpr(SymbolTable tbl) throws CompileError {
  780. int t;
  781. switch (lex.lookAhead()) {
  782. case '+' :
  783. case '-' :
  784. case PLUSPLUS :
  785. case MINUSMINUS :
  786. case '!' :
  787. case '~' :
  788. t = lex.get();
  789. if (t == '-') {
  790. int t2 = lex.lookAhead();
  791. switch (t2) {
  792. case LongConstant :
  793. case IntConstant :
  794. case CharConstant :
  795. lex.get();
  796. return new IntConst(-lex.getLong(), t2, lex.getLineNumber());
  797. case DoubleConstant :
  798. case FloatConstant :
  799. lex.get();
  800. return new DoubleConst(-lex.getDouble(), t2, lex.getLineNumber());
  801. default :
  802. break;
  803. }
  804. }
  805. return Expr.make(t, parseUnaryExpr(tbl), lex.getLineNumber());
  806. case '(' :
  807. return parseCast(tbl);
  808. default :
  809. return parsePostfix(tbl);
  810. }
  811. }
  812. /* cast.expr : "(" builtin.type ("[" "]")* ")" unary.expr
  813. | "(" class.type ("[" "]")* ")" unary.expr2
  814. unary.expr2 is a unary.expr beginning with "(", NULL, StringL,
  815. Identifier, THIS, SUPER, or NEW.
  816. Either "(int.class)" or "(String[].class)" is a not cast expression.
  817. */
  818. private ASTree parseCast(SymbolTable tbl) throws CompileError {
  819. int t = lex.lookAhead(1);
  820. if (isBuiltinType(t) && nextIsBuiltinCast()) {
  821. lex.get(); // '('
  822. lex.get(); // primitive type
  823. int dim = parseArrayDimension();
  824. if (lex.get() != ')')
  825. throw new CompileError(") is missing", lex);
  826. return new CastExpr(t, dim, parseUnaryExpr(tbl), lex.getLineNumber());
  827. }
  828. else if (t == Identifier && nextIsClassCast()) {
  829. lex.get(); // '('
  830. ASTList name = parseClassType(tbl);
  831. int dim = parseArrayDimension();
  832. if (lex.get() != ')')
  833. throw new CompileError(") is missing", lex);
  834. return new CastExpr(name, dim, parseUnaryExpr(tbl), lex.getLineNumber());
  835. }
  836. else
  837. return parsePostfix(tbl);
  838. }
  839. private boolean nextIsBuiltinCast() {
  840. @SuppressWarnings("unused")
  841. int t;
  842. int i = 2;
  843. while ((t = lex.lookAhead(i++)) == '[')
  844. if (lex.lookAhead(i++) != ']')
  845. return false;
  846. return lex.lookAhead(i - 1) == ')';
  847. }
  848. private boolean nextIsClassCast() {
  849. int i = nextIsClassType(1);
  850. if (i < 0)
  851. return false;
  852. int t = lex.lookAhead(i);
  853. if (t != ')')
  854. return false;
  855. t = lex.lookAhead(i + 1);
  856. return t == '(' || t == NULL || t == StringL
  857. || t == Identifier || t == THIS || t == SUPER || t == NEW
  858. || t == TRUE || t == FALSE || t == LongConstant
  859. || t == IntConstant || t == CharConstant
  860. || t == DoubleConstant || t == FloatConstant;
  861. }
  862. private int nextIsClassType(int i) {
  863. @SuppressWarnings("unused")
  864. int t;
  865. while (lex.lookAhead(++i) == '.')
  866. if (lex.lookAhead(++i) != Identifier)
  867. return -1;
  868. while ((t = lex.lookAhead(i++)) == '[')
  869. if (lex.lookAhead(i++) != ']')
  870. return -1;
  871. return i - 1;
  872. }
  873. /* array.dimension : [ "[" "]" ]*
  874. */
  875. private int parseArrayDimension() throws CompileError {
  876. int arrayDim = 0;
  877. while (lex.lookAhead() == '[') {
  878. ++arrayDim;
  879. lex.get();
  880. if (lex.get() != ']')
  881. throw new CompileError("] is missing", lex);
  882. }
  883. return arrayDim;
  884. }
  885. /* class.type : Identifier ( "." Identifier )*
  886. */
  887. private ASTList parseClassType(SymbolTable tbl) throws CompileError {
  888. ASTList list = null;
  889. for (;;) {
  890. if (lex.get() != Identifier)
  891. throw new SyntaxError(lex);
  892. list = ASTList.append(list, new Symbol(lex.getString(), lex.getLineNumber()), lex.getLineNumber());
  893. if (lex.lookAhead() == '.')
  894. lex.get();
  895. else
  896. break;
  897. }
  898. return list;
  899. }
  900. /* postfix.expr : number.literal
  901. * | primary.expr
  902. * | method.expr
  903. * | postfix.expr "++" | "--"
  904. * | postfix.expr "[" array.size "]"
  905. * | postfix.expr "." Identifier
  906. * | postfix.expr ( "[" "]" )* "." CLASS
  907. * | postfix.expr "#" Identifier
  908. * | postfix.expr "." SUPER
  909. *
  910. * "#" is not an operator of regular Java. It separates
  911. * a class name and a member name in an expression for static member
  912. * access. For example,
  913. * java.lang.Integer.toString(3) in regular Java
  914. * can be written like this:
  915. * java.lang.Integer#toString(3) for this compiler.
  916. */
  917. private ASTree parsePostfix(SymbolTable tbl) throws CompileError {
  918. int token = lex.lookAhead();
  919. switch (token) { // see also parseUnaryExpr()
  920. case LongConstant :
  921. case IntConstant :
  922. case CharConstant :
  923. lex.get();
  924. return new IntConst(lex.getLong(), token, lex.getLineNumber());
  925. case DoubleConstant :
  926. case FloatConstant :
  927. lex.get();
  928. return new DoubleConst(lex.getDouble(), token, lex.getLineNumber());
  929. default :
  930. break;
  931. }
  932. String str;
  933. ASTree index;
  934. ASTree expr = parsePrimaryExpr(tbl);
  935. int t;
  936. while (true) {
  937. switch (lex.lookAhead()) {
  938. case '(' :
  939. expr = parseMethodCall(tbl, expr);
  940. break;
  941. case '[' :
  942. if (lex.lookAhead(1) == ']') {
  943. int dim = parseArrayDimension();
  944. if (lex.get() != '.' || lex.get() != CLASS)
  945. throw new SyntaxError(lex);
  946. expr = parseDotClass(expr, dim);
  947. }
  948. else {
  949. index = parseArrayIndex(tbl);
  950. if (index == null)
  951. throw new SyntaxError(lex);
  952. expr = Expr.make(ARRAY, expr, index, lex.getLineNumber());
  953. }
  954. break;
  955. case PLUSPLUS :
  956. case MINUSMINUS :
  957. t = lex.get();
  958. expr = Expr.make(t, null, expr, lex.getLineNumber());
  959. break;
  960. case '.' :
  961. lex.get();
  962. t = lex.get();
  963. if (t == CLASS)
  964. expr = parseDotClass(expr, 0);
  965. else if (t == SUPER)
  966. expr = Expr.make('.', new Symbol(toClassName(expr), lex.getLineNumber()), new Keyword(t, lex.getLineNumber()), lex.getLineNumber());
  967. else if (t == Identifier) {
  968. str = lex.getString();
  969. expr = Expr.make('.', expr, new Member(str, lex.getLineNumber()), lex.getLineNumber());
  970. }
  971. else
  972. throw new CompileError("missing member name", lex);
  973. break;
  974. case '#' :
  975. lex.get();
  976. t = lex.get();
  977. if (t != Identifier)
  978. throw new CompileError("missing static member name", lex);
  979. str = lex.getString();
  980. expr = Expr.make(MEMBER, new Symbol(toClassName(expr), lex.getLineNumber()),
  981. new Member(str, lex.getLineNumber()), lex.getLineNumber());
  982. break;
  983. default :
  984. return expr;
  985. }
  986. }
  987. }
  988. /* Parse a .class expression on a class type. For example,
  989. * String.class => ('.' "String" "class")
  990. * String[].class => ('.' "[LString;" "class")
  991. */
  992. private ASTree parseDotClass(ASTree className, int dim)
  993. throws CompileError
  994. {
  995. String cname = toClassName(className);
  996. if (dim > 0) {
  997. StringBuilder sbuf = new StringBuilder();
  998. while (dim-- > 0)
  999. sbuf.append('[');
  1000. sbuf.append('L').append(cname.replace('.', '/')).append(';');
  1001. cname = sbuf.toString();
  1002. }
  1003. return Expr.make('.', new Symbol(cname, className.getLineNumber()), new Member("class", className.getLineNumber()), lex.getLineNumber());
  1004. }
  1005. /* Parses a .class expression on a built-in type. For example,
  1006. * int.class => ('#' "java.lang.Integer" "TYPE")
  1007. * int[].class => ('.' "[I", "class")
  1008. */
  1009. private ASTree parseDotClass(int builtinType, int dim)
  1010. throws CompileError
  1011. {
  1012. if (dim > 0) {
  1013. String cname = CodeGen.toJvmTypeName(builtinType, dim);
  1014. return Expr.make('.', new Symbol(cname, lex.getLineNumber()), new Member("class", lex.getLineNumber()), lex.getLineNumber());
  1015. }
  1016. String cname;
  1017. switch(builtinType) {
  1018. case BOOLEAN :
  1019. cname = "java.lang.Boolean";
  1020. break;
  1021. case BYTE :
  1022. cname = "java.lang.Byte";
  1023. break;
  1024. case CHAR :
  1025. cname = "java.lang.Character";
  1026. break;
  1027. case SHORT :
  1028. cname = "java.lang.Short";
  1029. break;
  1030. case INT :
  1031. cname = "java.lang.Integer";
  1032. break;
  1033. case LONG :
  1034. cname = "java.lang.Long";
  1035. break;
  1036. case FLOAT :
  1037. cname = "java.lang.Float";
  1038. break;
  1039. case DOUBLE :
  1040. cname = "java.lang.Double";
  1041. break;
  1042. case VOID :
  1043. cname = "java.lang.Void";
  1044. break;
  1045. default :
  1046. throw new CompileError("invalid builtin type: "
  1047. + builtinType, lex);
  1048. }
  1049. return Expr.make(MEMBER, new Symbol(cname, lex.getLineNumber()), new Member("TYPE", lex.getLineNumber()), lex.getLineNumber());
  1050. }
  1051. /* method.call : method.expr "(" argument.list ")"
  1052. * method.expr : THIS | SUPER | Identifier
  1053. * | postfix.expr "." Identifier
  1054. * | postfix.expr "#" Identifier
  1055. */
  1056. private ASTree parseMethodCall(SymbolTable tbl, ASTree expr)
  1057. throws CompileError
  1058. {
  1059. if (expr instanceof Keyword) {
  1060. int token = ((Keyword)expr).get();
  1061. if (token != THIS && token != SUPER)
  1062. throw new SyntaxError(lex);
  1063. }
  1064. else if (expr instanceof Symbol) // Identifier
  1065. ;
  1066. else if (expr instanceof Expr) {
  1067. int op = ((Expr)expr).getOperator();
  1068. if (op != '.' && op != MEMBER)
  1069. throw new SyntaxError(lex);
  1070. }
  1071. return CallExpr.makeCall(expr, parseArgumentList(tbl), lex.getLineNumber());
  1072. }
  1073. private String toClassName(ASTree name)
  1074. throws CompileError
  1075. {
  1076. StringBuilder sbuf = new StringBuilder();
  1077. toClassName(name, sbuf);
  1078. return sbuf.toString();
  1079. }
  1080. private void toClassName(ASTree name, StringBuilder sbuf)
  1081. throws CompileError
  1082. {
  1083. if (name instanceof Symbol) {
  1084. sbuf.append(((Symbol)name).get());
  1085. return;
  1086. }
  1087. else if (name instanceof Expr) {
  1088. Expr expr = (Expr)name;
  1089. if (expr.getOperator() == '.') {
  1090. toClassName(expr.oprand1(), sbuf);
  1091. sbuf.append('.');
  1092. toClassName(expr.oprand2(), sbuf);
  1093. return;
  1094. }
  1095. }
  1096. throw new CompileError("bad static member access", lex);
  1097. }
  1098. /* primary.expr : THIS | SUPER | TRUE | FALSE | NULL
  1099. * | StringL
  1100. * | Identifier
  1101. * | NEW new.expr
  1102. * | "(" expression ")"
  1103. * | builtin.type ( "[" "]" )* "." CLASS
  1104. *
  1105. * Identifier represents either a local variable name, a member name,
  1106. * or a class name.
  1107. */
  1108. private ASTree parsePrimaryExpr(SymbolTable tbl) throws CompileError {
  1109. int t;
  1110. String name;
  1111. Declarator decl;
  1112. ASTree expr;
  1113. switch (t = lex.get()) {
  1114. case THIS :
  1115. case SUPER :
  1116. case TRUE :
  1117. case FALSE :
  1118. case NULL :
  1119. return new Keyword(t, lex.getLineNumber());
  1120. case Identifier :
  1121. name = lex.getString();
  1122. decl = tbl.lookup(name);
  1123. if (decl == null)
  1124. return new Member(name, lex.getLineNumber()); // this or static member
  1125. return new Variable(name, decl, lex.getLineNumber()); // local variable
  1126. case StringL :
  1127. return new StringL(lex.getString(), lex.getLineNumber());
  1128. case NEW :
  1129. return parseNew(tbl);
  1130. case '(' :
  1131. expr = parseExpression(tbl);
  1132. if (lex.get() == ')')
  1133. return expr;
  1134. throw new CompileError(") is missing", lex);
  1135. default :
  1136. if (isBuiltinType(t) || t == VOID) {
  1137. int dim = parseArrayDimension();
  1138. if (lex.get() == '.' && lex.get() == CLASS)
  1139. return parseDotClass(t, dim);
  1140. }
  1141. throw new SyntaxError(lex);
  1142. }
  1143. }
  1144. /* new.expr : class.type "(" argument.list ")"
  1145. * | class.type array.size [ array.initializer ]
  1146. * | primitive.type array.size [ array.initializer ]
  1147. */
  1148. private NewExpr parseNew(SymbolTable tbl) throws CompileError {
  1149. ArrayInit init = null;
  1150. int t = lex.lookAhead();
  1151. if (isBuiltinType(t)) {
  1152. lex.get();
  1153. ASTList size = parseArraySize(tbl);
  1154. if (lex.lookAhead() == '{')
  1155. init = parseArrayInitializer(tbl);
  1156. return new NewExpr(t, size, init, lex.getLineNumber());
  1157. }
  1158. else if (t == Identifier) {
  1159. ASTList name = parseClassType(tbl);
  1160. t = lex.lookAhead();
  1161. if (t == '(') {
  1162. ASTList args = parseArgumentList(tbl);
  1163. return new NewExpr(name, args, lex.getLineNumber());
  1164. }
  1165. else if (t == '[') {
  1166. ASTList size = parseArraySize(tbl);
  1167. if (lex.lookAhead() == '{')
  1168. init = parseArrayInitializer(tbl);
  1169. return NewExpr.makeObjectArray(name, size, init, lex.getLineNumber());
  1170. }
  1171. }
  1172. throw new SyntaxError(lex);
  1173. }
  1174. /* array.size : [ array.index ]*
  1175. */
  1176. private ASTList parseArraySize(SymbolTable tbl) throws CompileError {
  1177. ASTList list = null;
  1178. while (lex.lookAhead() == '[')
  1179. list = ASTList.append(list, parseArrayIndex(tbl), lex.getLineNumber());
  1180. return list;
  1181. }
  1182. /* array.index : "[" [ expression ] "]"
  1183. */
  1184. private ASTree parseArrayIndex(SymbolTable tbl) throws CompileError {
  1185. lex.get(); // '['
  1186. if (lex.lookAhead() == ']') {
  1187. lex.get();
  1188. return null;
  1189. }
  1190. ASTree index = parseExpression(tbl);
  1191. if (lex.get() != ']')
  1192. throw new CompileError("] is missing", lex);
  1193. return index;
  1194. }
  1195. /* argument.list : "(" [ expression [ "," expression ]* ] ")"
  1196. */
  1197. private ASTList parseArgumentList(SymbolTable tbl) throws CompileError {
  1198. if (lex.get() != '(')
  1199. throw new CompileError("( is missing", lex);
  1200. ASTList list = null;
  1201. if (lex.lookAhead() != ')')
  1202. for (;;) {
  1203. list = ASTList.append(list, parseExpression(tbl), lex.getLineNumber());
  1204. if (lex.lookAhead() == ',')
  1205. lex.get();
  1206. else
  1207. break;
  1208. }
  1209. if (lex.get() != ')')
  1210. throw new CompileError(") is missing", lex);
  1211. return list;
  1212. }
  1213. }