Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

Parser.java 41KB

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