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 41KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357
  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);
  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));
  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)));
  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));
  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));
  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)));
  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);
  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()), list);
  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);
  188. }
  189. ASTList name = parseClassType(tbl);
  190. int dim = parseArrayDimension();
  191. return new Declarator(name, dim);
  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));
  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); // 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), parseStatement(tbl));
  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. if (lex.get() != '{')
  275. throw new SyntaxError(lex);
  276. Stmnt body = null;
  277. SymbolTable tbl2 = new SymbolTable(tbl);
  278. while (lex.lookAhead() != '}') {
  279. Stmnt s = parseStatement(tbl2);
  280. if (s != null)
  281. body = (Stmnt)ASTList.concat(body, new Stmnt(BLOCK, s));
  282. }
  283. lex.get(); // '}'
  284. if (body == null)
  285. return new Stmnt(BLOCK); // empty block
  286. return body;
  287. }
  288. /* if.statement : IF "(" expression ")" statement
  289. * [ ELSE statement ]
  290. */
  291. private Stmnt parseIf(SymbolTable tbl) throws CompileError {
  292. int t = lex.get(); // IF
  293. ASTree expr = parseParExpression(tbl);
  294. Stmnt thenp = parseStatement(tbl);
  295. Stmnt elsep;
  296. if (lex.lookAhead() == ELSE) {
  297. lex.get();
  298. elsep = parseStatement(tbl);
  299. }
  300. else
  301. elsep = null;
  302. return new Stmnt(t, expr, new ASTList(thenp, new ASTList(elsep)));
  303. }
  304. /* while.statement : WHILE "(" expression ")" statement
  305. */
  306. private Stmnt parseWhile(SymbolTable tbl)
  307. throws CompileError
  308. {
  309. int t = lex.get(); // WHILE
  310. ASTree expr = parseParExpression(tbl);
  311. Stmnt body = parseStatement(tbl);
  312. return new Stmnt(t, expr, body);
  313. }
  314. /* do.statement : DO statement WHILE "(" expression ")" ";"
  315. */
  316. private Stmnt parseDo(SymbolTable tbl) throws CompileError {
  317. int t = lex.get(); // DO
  318. Stmnt body = parseStatement(tbl);
  319. if (lex.get() != WHILE || lex.get() != '(')
  320. throw new SyntaxError(lex);
  321. ASTree expr = parseExpression(tbl);
  322. if (lex.get() != ')' || lex.get() != ';')
  323. throw new SyntaxError(lex);
  324. return new Stmnt(t, expr, body);
  325. }
  326. /* for.statement : FOR "(" decl.or.expr expression ";" expression ")"
  327. * statement
  328. */
  329. private Stmnt parseFor(SymbolTable tbl) throws CompileError {
  330. Stmnt expr1, expr3;
  331. ASTree expr2;
  332. int t = lex.get(); // FOR
  333. SymbolTable tbl2 = new SymbolTable(tbl);
  334. if (lex.get() != '(')
  335. throw new SyntaxError(lex);
  336. if (lex.lookAhead() == ';') {
  337. lex.get();
  338. expr1 = null;
  339. }
  340. else
  341. expr1 = parseDeclarationOrExpression(tbl2, true);
  342. if (lex.lookAhead() == ';')
  343. expr2 = null;
  344. else
  345. expr2 = parseExpression(tbl2);
  346. if (lex.get() != ';')
  347. throw new CompileError("; is missing", lex);
  348. if (lex.lookAhead() == ')')
  349. expr3 = null;
  350. else
  351. expr3 = parseExprList(tbl2);
  352. if (lex.get() != ')')
  353. throw new CompileError(") is missing", lex);
  354. Stmnt body = parseStatement(tbl2);
  355. return new Stmnt(t, expr1, new ASTList(expr2,
  356. new ASTList(expr3, body)));
  357. }
  358. /* switch.statement : SWITCH "(" expression ")" "{" switch.block "}"
  359. *
  360. * swtich.block : ( switch.label statement* )*
  361. *
  362. * swtich.label : DEFAULT ":"
  363. * | CASE const.expression ":"
  364. */
  365. private Stmnt parseSwitch(SymbolTable tbl) throws CompileError {
  366. int t = lex.get(); // SWITCH
  367. ASTree expr = parseParExpression(tbl);
  368. Stmnt body = parseSwitchBlock(tbl);
  369. return new Stmnt(t, expr, body);
  370. }
  371. private Stmnt parseSwitchBlock(SymbolTable tbl) throws CompileError {
  372. if (lex.get() != '{')
  373. throw new SyntaxError(lex);
  374. SymbolTable tbl2 = new SymbolTable(tbl);
  375. Stmnt s = parseStmntOrCase(tbl2);
  376. if (s == null)
  377. throw new CompileError("empty switch block", lex);
  378. int op = s.getOperator();
  379. if (op != CASE && op != DEFAULT)
  380. throw new CompileError("no case or default in a switch block",
  381. lex);
  382. Stmnt body = new Stmnt(BLOCK, s);
  383. while (lex.lookAhead() != '}') {
  384. Stmnt s2 = parseStmntOrCase(tbl2);
  385. if (s2 != null) {
  386. int op2 = s2.getOperator();
  387. if (op2 == CASE || op2 == DEFAULT) {
  388. body = (Stmnt)ASTList.concat(body, new Stmnt(BLOCK, s2));
  389. s = s2;
  390. }
  391. else
  392. s = (Stmnt)ASTList.concat(s, new Stmnt(BLOCK, s2));
  393. }
  394. }
  395. lex.get(); // '}'
  396. return body;
  397. }
  398. private Stmnt parseStmntOrCase(SymbolTable tbl) throws CompileError {
  399. int t = lex.lookAhead();
  400. if (t != CASE && t != DEFAULT)
  401. return parseStatement(tbl);
  402. lex.get();
  403. Stmnt s;
  404. if (t == CASE)
  405. s = new Stmnt(t, parseExpression(tbl));
  406. else
  407. s = new Stmnt(DEFAULT);
  408. if (lex.get() != ':')
  409. throw new CompileError(": is missing", lex);
  410. return s;
  411. }
  412. /* synchronized.statement :
  413. * SYNCHRONIZED "(" expression ")" block.statement
  414. */
  415. private Stmnt parseSynchronized(SymbolTable tbl) throws CompileError {
  416. int t = lex.get(); // SYNCHRONIZED
  417. if (lex.get() != '(')
  418. throw new SyntaxError(lex);
  419. ASTree expr = parseExpression(tbl);
  420. if (lex.get() != ')')
  421. throw new SyntaxError(lex);
  422. Stmnt body = parseBlock(tbl);
  423. return new Stmnt(t, expr, body);
  424. }
  425. /* try.statement
  426. * : TRY block.statement
  427. * [ CATCH "(" class.type Identifier ")" block.statement ]*
  428. * [ FINALLY block.statement ]*
  429. */
  430. private Stmnt parseTry(SymbolTable tbl) throws CompileError {
  431. lex.get(); // TRY
  432. Stmnt block = parseBlock(tbl);
  433. ASTList catchList = null;
  434. while (lex.lookAhead() == CATCH) {
  435. lex.get(); // CATCH
  436. if (lex.get() != '(')
  437. throw new SyntaxError(lex);
  438. SymbolTable tbl2 = new SymbolTable(tbl);
  439. Declarator d = parseFormalParam(tbl2);
  440. if (d.getArrayDim() > 0 || d.getType() != CLASS)
  441. throw new SyntaxError(lex);
  442. if (lex.get() != ')')
  443. throw new SyntaxError(lex);
  444. Stmnt b = parseBlock(tbl2);
  445. catchList = ASTList.append(catchList, new Pair(d, b));
  446. }
  447. Stmnt finallyBlock = null;
  448. if (lex.lookAhead() == FINALLY) {
  449. lex.get(); // FINALLY
  450. finallyBlock = parseBlock(tbl);
  451. }
  452. return Stmnt.make(TRY, block, catchList, finallyBlock);
  453. }
  454. /* return.statement : RETURN [ expression ] ";"
  455. */
  456. private Stmnt parseReturn(SymbolTable tbl) throws CompileError {
  457. int t = lex.get(); // RETURN
  458. Stmnt s = new Stmnt(t);
  459. if (lex.lookAhead() != ';')
  460. s.setLeft(parseExpression(tbl));
  461. if (lex.get() != ';')
  462. throw new CompileError("; is missing", lex);
  463. return s;
  464. }
  465. /* throw.statement : THROW expression ";"
  466. */
  467. private Stmnt parseThrow(SymbolTable tbl) throws CompileError {
  468. int t = lex.get(); // THROW
  469. ASTree expr = parseExpression(tbl);
  470. if (lex.get() != ';')
  471. throw new CompileError("; is missing", lex);
  472. return new Stmnt(t, expr);
  473. }
  474. /* break.statement : BREAK [ Identifier ] ";"
  475. */
  476. private Stmnt parseBreak(SymbolTable tbl)
  477. throws CompileError
  478. {
  479. return parseContinue(tbl);
  480. }
  481. /* continue.statement : CONTINUE [ Identifier ] ";"
  482. */
  483. private Stmnt parseContinue(SymbolTable tbl)
  484. throws CompileError
  485. {
  486. int t = lex.get(); // CONTINUE
  487. Stmnt s = new Stmnt(t);
  488. int t2 = lex.get();
  489. if (t2 == Identifier) {
  490. s.setLeft(new Symbol(lex.getString()));
  491. t2 = lex.get();
  492. }
  493. if (t2 != ';')
  494. throw new CompileError("; is missing", lex);
  495. return s;
  496. }
  497. /* declaration.or.expression
  498. * : [ FINAL ] built-in-type array.dimension declarators
  499. * | [ FINAL ] class.type array.dimension declarators
  500. * | expression ';'
  501. * | expr.list ';' if exprList is true
  502. *
  503. * Note: FINAL is currently ignored. This must be fixed
  504. * in future.
  505. */
  506. private Stmnt parseDeclarationOrExpression(SymbolTable tbl,
  507. boolean exprList)
  508. throws CompileError
  509. {
  510. int t = lex.lookAhead();
  511. while (t == FINAL) {
  512. lex.get();
  513. t = lex.lookAhead();
  514. }
  515. if (isBuiltinType(t)) {
  516. t = lex.get();
  517. int dim = parseArrayDimension();
  518. return parseDeclarators(tbl, new Declarator(t, dim));
  519. }
  520. else if (t == Identifier) {
  521. int i = nextIsClassType(0);
  522. if (i >= 0)
  523. if (lex.lookAhead(i) == Identifier) {
  524. ASTList name = parseClassType(tbl);
  525. int dim = parseArrayDimension();
  526. return parseDeclarators(tbl, new Declarator(name, dim));
  527. }
  528. }
  529. Stmnt expr;
  530. if (exprList)
  531. expr = parseExprList(tbl);
  532. else
  533. expr = new Stmnt(EXPR, parseExpression(tbl));
  534. if (lex.get() != ';')
  535. throw new CompileError("; is missing", lex);
  536. return expr;
  537. }
  538. /* expr.list : ( expression ',')* expression
  539. */
  540. private Stmnt parseExprList(SymbolTable tbl) throws CompileError {
  541. Stmnt expr = null;
  542. for (;;) {
  543. Stmnt e = new Stmnt(EXPR, parseExpression(tbl));
  544. expr = (Stmnt)ASTList.concat(expr, new Stmnt(BLOCK, e));
  545. if (lex.lookAhead() == ',')
  546. lex.get();
  547. else
  548. return expr;
  549. }
  550. }
  551. /* declarators : declarator [ ',' declarator ]* ';'
  552. */
  553. private Stmnt parseDeclarators(SymbolTable tbl, Declarator d)
  554. throws CompileError
  555. {
  556. Stmnt decl = null;
  557. for (;;) {
  558. decl = (Stmnt)ASTList.concat(decl,
  559. new Stmnt(DECL, parseDeclarator(tbl, d)));
  560. int t = lex.get();
  561. if (t == ';')
  562. return decl;
  563. else if (t != ',')
  564. throw new CompileError("; is missing", lex);
  565. }
  566. }
  567. /* declarator : Identifier array.dimension [ '=' initializer ]
  568. */
  569. private Declarator parseDeclarator(SymbolTable tbl, Declarator d)
  570. throws CompileError
  571. {
  572. if (lex.get() != Identifier || d.getType() == VOID)
  573. throw new SyntaxError(lex);
  574. String name = lex.getString();
  575. Symbol symbol = new Symbol(name);
  576. int dim = parseArrayDimension();
  577. ASTree init = null;
  578. if (lex.lookAhead() == '=') {
  579. lex.get();
  580. init = parseInitializer(tbl);
  581. }
  582. Declarator decl = d.make(symbol, dim, init);
  583. tbl.append(name, decl);
  584. return decl;
  585. }
  586. /* initializer : expression | array.initializer
  587. */
  588. private ASTree parseInitializer(SymbolTable tbl) throws CompileError {
  589. if (lex.lookAhead() == '{')
  590. return parseArrayInitializer(tbl);
  591. return parseExpression(tbl);
  592. }
  593. /* array.initializer :
  594. * '{' (( array.initializer | expression ) ',')* '}'
  595. */
  596. private ArrayInit parseArrayInitializer(SymbolTable tbl)
  597. throws CompileError
  598. {
  599. lex.get(); // '{'
  600. if(lex.lookAhead() == '}'){
  601. lex.get();
  602. return new ArrayInit(new IntConst(0,TokenId.IntConstant));
  603. }
  604. ASTree expr = parseExpression(tbl);
  605. ArrayInit init = new ArrayInit(expr);
  606. while (lex.lookAhead() == ',') {
  607. lex.get();
  608. expr = parseExpression(tbl);
  609. ASTList.append(init, expr);
  610. }
  611. if (lex.get() != '}')
  612. throw new SyntaxError(lex);
  613. return init;
  614. }
  615. /* par.expression : '(' expression ')'
  616. */
  617. private ASTree parseParExpression(SymbolTable tbl) throws CompileError {
  618. if (lex.get() != '(')
  619. throw new SyntaxError(lex);
  620. ASTree expr = parseExpression(tbl);
  621. if (lex.get() != ')')
  622. throw new SyntaxError(lex);
  623. return expr;
  624. }
  625. /* expression : conditional.expr
  626. * | conditional.expr assign.op expression (right-to-left)
  627. */
  628. public ASTree parseExpression(SymbolTable tbl) throws CompileError {
  629. ASTree left = parseConditionalExpr(tbl);
  630. if (!isAssignOp(lex.lookAhead()))
  631. return left;
  632. int t = lex.get();
  633. ASTree right = parseExpression(tbl);
  634. return AssignExpr.makeAssign(t, left, right);
  635. }
  636. private static boolean isAssignOp(int t) {
  637. return t == '=' || t == MOD_E || t == AND_E
  638. || t == MUL_E || t == PLUS_E || t == MINUS_E || t == DIV_E
  639. || t == EXOR_E || t == OR_E || t == LSHIFT_E
  640. || t == RSHIFT_E || t == ARSHIFT_E;
  641. }
  642. /* conditional.expr (right-to-left)
  643. * : logical.or.expr [ '?' expression ':' conditional.expr ]
  644. */
  645. private ASTree parseConditionalExpr(SymbolTable tbl) throws CompileError {
  646. ASTree cond = parseBinaryExpr(tbl);
  647. if (lex.lookAhead() == '?') {
  648. lex.get();
  649. ASTree thenExpr = parseExpression(tbl);
  650. if (lex.get() != ':')
  651. throw new CompileError(": is missing", lex);
  652. ASTree elseExpr = parseExpression(tbl);
  653. return new CondExpr(cond, thenExpr, elseExpr);
  654. }
  655. return cond;
  656. }
  657. /* logical.or.expr 10 (operator precedence)
  658. * : logical.and.expr
  659. * | logical.or.expr OROR logical.and.expr left-to-right
  660. *
  661. * logical.and.expr 9
  662. * : inclusive.or.expr
  663. * | logical.and.expr ANDAND inclusive.or.expr
  664. *
  665. * inclusive.or.expr 8
  666. * : exclusive.or.expr
  667. * | inclusive.or.expr "|" exclusive.or.expr
  668. *
  669. * exclusive.or.expr 7
  670. * : and.expr
  671. * | exclusive.or.expr "^" and.expr
  672. *
  673. * and.expr 6
  674. * : equality.expr
  675. * | and.expr "&" equality.expr
  676. *
  677. * equality.expr 5
  678. * : relational.expr
  679. * | equality.expr (EQ | NEQ) relational.expr
  680. *
  681. * relational.expr 4
  682. * : shift.expr
  683. * | relational.expr (LE | GE | "<" | ">") shift.expr
  684. * | relational.expr INSTANCEOF class.type ("[" "]")*
  685. *
  686. * shift.expr 3
  687. * : additive.expr
  688. * | shift.expr (LSHIFT | RSHIFT | ARSHIFT) additive.expr
  689. *
  690. * additive.expr 2
  691. * : multiply.expr
  692. * | additive.expr ("+" | "-") multiply.expr
  693. *
  694. * multiply.expr 1
  695. * : unary.expr
  696. * | multiply.expr ("*" | "/" | "%") unary.expr
  697. */
  698. private ASTree parseBinaryExpr(SymbolTable tbl) throws CompileError {
  699. ASTree expr = parseUnaryExpr(tbl);
  700. for (;;) {
  701. int t = lex.lookAhead();
  702. int p = getOpPrecedence(t);
  703. if (p == 0)
  704. return expr;
  705. expr = binaryExpr2(tbl, expr, p);
  706. }
  707. }
  708. private ASTree parseInstanceOf(SymbolTable tbl, ASTree expr)
  709. throws CompileError
  710. {
  711. int t = lex.lookAhead();
  712. if (isBuiltinType(t)) {
  713. lex.get(); // primitive type
  714. int dim = parseArrayDimension();
  715. return new InstanceOfExpr(t, dim, expr);
  716. }
  717. ASTList name = parseClassType(tbl);
  718. int dim = parseArrayDimension();
  719. return new InstanceOfExpr(name, dim, expr);
  720. }
  721. private ASTree binaryExpr2(SymbolTable tbl, ASTree expr, int prec)
  722. throws CompileError
  723. {
  724. int t = lex.get();
  725. if (t == INSTANCEOF)
  726. return parseInstanceOf(tbl, expr);
  727. ASTree expr2 = parseUnaryExpr(tbl);
  728. for (;;) {
  729. int t2 = lex.lookAhead();
  730. int p2 = getOpPrecedence(t2);
  731. if (p2 != 0 && prec > p2)
  732. expr2 = binaryExpr2(tbl, expr2, p2);
  733. else
  734. return BinExpr.makeBin(t, expr, expr2);
  735. }
  736. }
  737. // !"#$%&'( )*+,-./0 12345678 9:;<=>?
  738. private static final int[] binaryOpPrecedence
  739. = { 0, 0, 0, 0, 1, 6, 0, 0,
  740. 0, 1, 2, 0, 2, 0, 1, 0,
  741. 0, 0, 0, 0, 0, 0, 0, 0,
  742. 0, 0, 0, 4, 0, 4, 0 };
  743. private int getOpPrecedence(int c) {
  744. if ('!' <= c && c <= '?')
  745. return binaryOpPrecedence[c - '!'];
  746. else if (c == '^')
  747. return 7;
  748. else if (c == '|')
  749. return 8;
  750. else if (c == ANDAND)
  751. return 9;
  752. else if (c == OROR)
  753. return 10;
  754. else if (c == EQ || c == NEQ)
  755. return 5;
  756. else if (c == LE || c == GE || c == INSTANCEOF)
  757. return 4;
  758. else if (c == LSHIFT || c == RSHIFT || c == ARSHIFT)
  759. return 3;
  760. else
  761. return 0; // not a binary operator
  762. }
  763. /* unary.expr : "++"|"--" unary.expr
  764. | "+"|"-" unary.expr
  765. | "!"|"~" unary.expr
  766. | cast.expr
  767. | postfix.expr
  768. unary.expr.not.plus.minus is a unary expression starting without
  769. "+", "-", "++", or "--".
  770. */
  771. private ASTree parseUnaryExpr(SymbolTable tbl) throws CompileError {
  772. int t;
  773. switch (lex.lookAhead()) {
  774. case '+' :
  775. case '-' :
  776. case PLUSPLUS :
  777. case MINUSMINUS :
  778. case '!' :
  779. case '~' :
  780. t = lex.get();
  781. if (t == '-') {
  782. int t2 = lex.lookAhead();
  783. switch (t2) {
  784. case LongConstant :
  785. case IntConstant :
  786. case CharConstant :
  787. lex.get();
  788. return new IntConst(-lex.getLong(), t2);
  789. case DoubleConstant :
  790. case FloatConstant :
  791. lex.get();
  792. return new DoubleConst(-lex.getDouble(), t2);
  793. default :
  794. break;
  795. }
  796. }
  797. return Expr.make(t, parseUnaryExpr(tbl));
  798. case '(' :
  799. return parseCast(tbl);
  800. default :
  801. return parsePostfix(tbl);
  802. }
  803. }
  804. /* cast.expr : "(" builtin.type ("[" "]")* ")" unary.expr
  805. | "(" class.type ("[" "]")* ")" unary.expr2
  806. unary.expr2 is a unary.expr beginning with "(", NULL, StringL,
  807. Identifier, THIS, SUPER, or NEW.
  808. Either "(int.class)" or "(String[].class)" is a not cast expression.
  809. */
  810. private ASTree parseCast(SymbolTable tbl) throws CompileError {
  811. int t = lex.lookAhead(1);
  812. if (isBuiltinType(t) && nextIsBuiltinCast()) {
  813. lex.get(); // '('
  814. lex.get(); // primitive type
  815. int dim = parseArrayDimension();
  816. if (lex.get() != ')')
  817. throw new CompileError(") is missing", lex);
  818. return new CastExpr(t, dim, parseUnaryExpr(tbl));
  819. }
  820. else if (t == Identifier && nextIsClassCast()) {
  821. lex.get(); // '('
  822. ASTList name = parseClassType(tbl);
  823. int dim = parseArrayDimension();
  824. if (lex.get() != ')')
  825. throw new CompileError(") is missing", lex);
  826. return new CastExpr(name, dim, parseUnaryExpr(tbl));
  827. }
  828. else
  829. return parsePostfix(tbl);
  830. }
  831. private boolean nextIsBuiltinCast() {
  832. @SuppressWarnings("unused")
  833. int t;
  834. int i = 2;
  835. while ((t = lex.lookAhead(i++)) == '[')
  836. if (lex.lookAhead(i++) != ']')
  837. return false;
  838. return lex.lookAhead(i - 1) == ')';
  839. }
  840. private boolean nextIsClassCast() {
  841. int i = nextIsClassType(1);
  842. if (i < 0)
  843. return false;
  844. int t = lex.lookAhead(i);
  845. if (t != ')')
  846. return false;
  847. t = lex.lookAhead(i + 1);
  848. return t == '(' || t == NULL || t == StringL
  849. || t == Identifier || t == THIS || t == SUPER || t == NEW
  850. || t == TRUE || t == FALSE || t == LongConstant
  851. || t == IntConstant || t == CharConstant
  852. || t == DoubleConstant || t == FloatConstant;
  853. }
  854. private int nextIsClassType(int i) {
  855. @SuppressWarnings("unused")
  856. int t;
  857. while (lex.lookAhead(++i) == '.')
  858. if (lex.lookAhead(++i) != Identifier)
  859. return -1;
  860. while ((t = lex.lookAhead(i++)) == '[')
  861. if (lex.lookAhead(i++) != ']')
  862. return -1;
  863. return i - 1;
  864. }
  865. /* array.dimension : [ "[" "]" ]*
  866. */
  867. private int parseArrayDimension() throws CompileError {
  868. int arrayDim = 0;
  869. while (lex.lookAhead() == '[') {
  870. ++arrayDim;
  871. lex.get();
  872. if (lex.get() != ']')
  873. throw new CompileError("] is missing", lex);
  874. }
  875. return arrayDim;
  876. }
  877. /* class.type : Identifier ( "." Identifier )*
  878. */
  879. private ASTList parseClassType(SymbolTable tbl) throws CompileError {
  880. ASTList list = null;
  881. for (;;) {
  882. if (lex.get() != Identifier)
  883. throw new SyntaxError(lex);
  884. list = ASTList.append(list, new Symbol(lex.getString()));
  885. if (lex.lookAhead() == '.')
  886. lex.get();
  887. else
  888. break;
  889. }
  890. return list;
  891. }
  892. /* postfix.expr : number.literal
  893. * | primary.expr
  894. * | method.expr
  895. * | postfix.expr "++" | "--"
  896. * | postfix.expr "[" array.size "]"
  897. * | postfix.expr "." Identifier
  898. * | postfix.expr ( "[" "]" )* "." CLASS
  899. * | postfix.expr "#" Identifier
  900. * | postfix.expr "." SUPER
  901. *
  902. * "#" is not an operator of regular Java. It separates
  903. * a class name and a member name in an expression for static member
  904. * access. For example,
  905. * java.lang.Integer.toString(3) in regular Java
  906. * can be written like this:
  907. * java.lang.Integer#toString(3) for this compiler.
  908. */
  909. private ASTree parsePostfix(SymbolTable tbl) throws CompileError {
  910. int token = lex.lookAhead();
  911. switch (token) { // see also parseUnaryExpr()
  912. case LongConstant :
  913. case IntConstant :
  914. case CharConstant :
  915. lex.get();
  916. return new IntConst(lex.getLong(), token);
  917. case DoubleConstant :
  918. case FloatConstant :
  919. lex.get();
  920. return new DoubleConst(lex.getDouble(), token);
  921. default :
  922. break;
  923. }
  924. String str;
  925. ASTree index;
  926. ASTree expr = parsePrimaryExpr(tbl);
  927. int t;
  928. while (true) {
  929. switch (lex.lookAhead()) {
  930. case '(' :
  931. expr = parseMethodCall(tbl, expr);
  932. break;
  933. case '[' :
  934. if (lex.lookAhead(1) == ']') {
  935. int dim = parseArrayDimension();
  936. if (lex.get() != '.' || lex.get() != CLASS)
  937. throw new SyntaxError(lex);
  938. expr = parseDotClass(expr, dim);
  939. }
  940. else {
  941. index = parseArrayIndex(tbl);
  942. if (index == null)
  943. throw new SyntaxError(lex);
  944. expr = Expr.make(ARRAY, expr, index);
  945. }
  946. break;
  947. case PLUSPLUS :
  948. case MINUSMINUS :
  949. t = lex.get();
  950. expr = Expr.make(t, null, expr);
  951. break;
  952. case '.' :
  953. lex.get();
  954. t = lex.get();
  955. if (t == CLASS)
  956. expr = parseDotClass(expr, 0);
  957. else if (t == SUPER)
  958. expr = Expr.make('.', new Symbol(toClassName(expr)), new Keyword(t));
  959. else if (t == Identifier) {
  960. str = lex.getString();
  961. expr = Expr.make('.', expr, new Member(str));
  962. }
  963. else
  964. throw new CompileError("missing member name", lex);
  965. break;
  966. case '#' :
  967. lex.get();
  968. t = lex.get();
  969. if (t != Identifier)
  970. throw new CompileError("missing static member name", lex);
  971. str = lex.getString();
  972. expr = Expr.make(MEMBER, new Symbol(toClassName(expr)),
  973. new Member(str));
  974. break;
  975. default :
  976. return expr;
  977. }
  978. }
  979. }
  980. /* Parse a .class expression on a class type. For example,
  981. * String.class => ('.' "String" "class")
  982. * String[].class => ('.' "[LString;" "class")
  983. */
  984. private ASTree parseDotClass(ASTree className, int dim)
  985. throws CompileError
  986. {
  987. String cname = toClassName(className);
  988. if (dim > 0) {
  989. StringBuffer sbuf = new StringBuffer();
  990. while (dim-- > 0)
  991. sbuf.append('[');
  992. sbuf.append('L').append(cname.replace('.', '/')).append(';');
  993. cname = sbuf.toString();
  994. }
  995. return Expr.make('.', new Symbol(cname), new Member("class"));
  996. }
  997. /* Parses a .class expression on a built-in type. For example,
  998. * int.class => ('#' "java.lang.Integer" "TYPE")
  999. * int[].class => ('.' "[I", "class")
  1000. */
  1001. private ASTree parseDotClass(int builtinType, int dim)
  1002. throws CompileError
  1003. {
  1004. if (dim > 0) {
  1005. String cname = CodeGen.toJvmTypeName(builtinType, dim);
  1006. return Expr.make('.', new Symbol(cname), new Member("class"));
  1007. }
  1008. String cname;
  1009. switch(builtinType) {
  1010. case BOOLEAN :
  1011. cname = "java.lang.Boolean";
  1012. break;
  1013. case BYTE :
  1014. cname = "java.lang.Byte";
  1015. break;
  1016. case CHAR :
  1017. cname = "java.lang.Character";
  1018. break;
  1019. case SHORT :
  1020. cname = "java.lang.Short";
  1021. break;
  1022. case INT :
  1023. cname = "java.lang.Integer";
  1024. break;
  1025. case LONG :
  1026. cname = "java.lang.Long";
  1027. break;
  1028. case FLOAT :
  1029. cname = "java.lang.Float";
  1030. break;
  1031. case DOUBLE :
  1032. cname = "java.lang.Double";
  1033. break;
  1034. case VOID :
  1035. cname = "java.lang.Void";
  1036. break;
  1037. default :
  1038. throw new CompileError("invalid builtin type: "
  1039. + builtinType);
  1040. }
  1041. return Expr.make(MEMBER, new Symbol(cname), new Member("TYPE"));
  1042. }
  1043. /* method.call : method.expr "(" argument.list ")"
  1044. * method.expr : THIS | SUPER | Identifier
  1045. * | postfix.expr "." Identifier
  1046. * | postfix.expr "#" Identifier
  1047. */
  1048. private ASTree parseMethodCall(SymbolTable tbl, ASTree expr)
  1049. throws CompileError
  1050. {
  1051. if (expr instanceof Keyword) {
  1052. int token = ((Keyword)expr).get();
  1053. if (token != THIS && token != SUPER)
  1054. throw new SyntaxError(lex);
  1055. }
  1056. else if (expr instanceof Symbol) // Identifier
  1057. ;
  1058. else if (expr instanceof Expr) {
  1059. int op = ((Expr)expr).getOperator();
  1060. if (op != '.' && op != MEMBER)
  1061. throw new SyntaxError(lex);
  1062. }
  1063. return CallExpr.makeCall(expr, parseArgumentList(tbl));
  1064. }
  1065. private String toClassName(ASTree name)
  1066. throws CompileError
  1067. {
  1068. StringBuffer sbuf = new StringBuffer();
  1069. toClassName(name, sbuf);
  1070. return sbuf.toString();
  1071. }
  1072. private void toClassName(ASTree name, StringBuffer sbuf)
  1073. throws CompileError
  1074. {
  1075. if (name instanceof Symbol) {
  1076. sbuf.append(((Symbol)name).get());
  1077. return;
  1078. }
  1079. else if (name instanceof Expr) {
  1080. Expr expr = (Expr)name;
  1081. if (expr.getOperator() == '.') {
  1082. toClassName(expr.oprand1(), sbuf);
  1083. sbuf.append('.');
  1084. toClassName(expr.oprand2(), sbuf);
  1085. return;
  1086. }
  1087. }
  1088. throw new CompileError("bad static member access", lex);
  1089. }
  1090. /* primary.expr : THIS | SUPER | TRUE | FALSE | NULL
  1091. * | StringL
  1092. * | Identifier
  1093. * | NEW new.expr
  1094. * | "(" expression ")"
  1095. * | builtin.type ( "[" "]" )* "." CLASS
  1096. *
  1097. * Identifier represents either a local variable name, a member name,
  1098. * or a class name.
  1099. */
  1100. private ASTree parsePrimaryExpr(SymbolTable tbl) throws CompileError {
  1101. int t;
  1102. String name;
  1103. Declarator decl;
  1104. ASTree expr;
  1105. switch (t = lex.get()) {
  1106. case THIS :
  1107. case SUPER :
  1108. case TRUE :
  1109. case FALSE :
  1110. case NULL :
  1111. return new Keyword(t);
  1112. case Identifier :
  1113. name = lex.getString();
  1114. decl = tbl.lookup(name);
  1115. if (decl == null)
  1116. return new Member(name); // this or static member
  1117. return new Variable(name, decl); // local variable
  1118. case StringL :
  1119. return new StringL(lex.getString());
  1120. case NEW :
  1121. return parseNew(tbl);
  1122. case '(' :
  1123. expr = parseExpression(tbl);
  1124. if (lex.get() == ')')
  1125. return expr;
  1126. throw new CompileError(") is missing", lex);
  1127. default :
  1128. if (isBuiltinType(t) || t == VOID) {
  1129. int dim = parseArrayDimension();
  1130. if (lex.get() == '.' && lex.get() == CLASS)
  1131. return parseDotClass(t, dim);
  1132. }
  1133. throw new SyntaxError(lex);
  1134. }
  1135. }
  1136. /* new.expr : class.type "(" argument.list ")"
  1137. * | class.type array.size [ array.initializer ]
  1138. * | primitive.type array.size [ array.initializer ]
  1139. */
  1140. private NewExpr parseNew(SymbolTable tbl) throws CompileError {
  1141. ArrayInit init = null;
  1142. int t = lex.lookAhead();
  1143. if (isBuiltinType(t)) {
  1144. lex.get();
  1145. ASTList size = parseArraySize(tbl);
  1146. if (lex.lookAhead() == '{')
  1147. init = parseArrayInitializer(tbl);
  1148. return new NewExpr(t, size, init);
  1149. }
  1150. else if (t == Identifier) {
  1151. ASTList name = parseClassType(tbl);
  1152. t = lex.lookAhead();
  1153. if (t == '(') {
  1154. ASTList args = parseArgumentList(tbl);
  1155. return new NewExpr(name, args);
  1156. }
  1157. else if (t == '[') {
  1158. ASTList size = parseArraySize(tbl);
  1159. if (lex.lookAhead() == '{')
  1160. init = parseArrayInitializer(tbl);
  1161. return NewExpr.makeObjectArray(name, size, init);
  1162. }
  1163. }
  1164. throw new SyntaxError(lex);
  1165. }
  1166. /* array.size : [ array.index ]*
  1167. */
  1168. private ASTList parseArraySize(SymbolTable tbl) throws CompileError {
  1169. ASTList list = null;
  1170. while (lex.lookAhead() == '[')
  1171. list = ASTList.append(list, parseArrayIndex(tbl));
  1172. return list;
  1173. }
  1174. /* array.index : "[" [ expression ] "]"
  1175. */
  1176. private ASTree parseArrayIndex(SymbolTable tbl) throws CompileError {
  1177. lex.get(); // '['
  1178. if (lex.lookAhead() == ']') {
  1179. lex.get();
  1180. return null;
  1181. }
  1182. ASTree index = parseExpression(tbl);
  1183. if (lex.get() != ']')
  1184. throw new CompileError("] is missing", lex);
  1185. return index;
  1186. }
  1187. /* argument.list : "(" [ expression [ "," expression ]* ] ")"
  1188. */
  1189. private ASTList parseArgumentList(SymbolTable tbl) throws CompileError {
  1190. if (lex.get() != '(')
  1191. throw new CompileError("( is missing", lex);
  1192. ASTList list = null;
  1193. if (lex.lookAhead() != ')')
  1194. for (;;) {
  1195. list = ASTList.append(list, parseExpression(tbl));
  1196. if (lex.lookAhead() == ',')
  1197. lex.get();
  1198. else
  1199. break;
  1200. }
  1201. if (lex.get() != ')')
  1202. throw new CompileError(") is missing", lex);
  1203. return list;
  1204. }
  1205. }