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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137
  1. /*
  2. * Javassist, a Java-bytecode translator toolkit.
  3. * Copyright (C) 1999-2003 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. if (lex.get() != '(')
  276. throw new SyntaxError(lex);
  277. ASTree expr = parseExpression(tbl);
  278. if (lex.get() != ')')
  279. throw new SyntaxError(lex);
  280. Stmnt thenp = parseStatement(tbl);
  281. Stmnt elsep;
  282. if (lex.lookAhead() == ELSE) {
  283. lex.get();
  284. elsep = parseStatement(tbl);
  285. }
  286. else
  287. elsep = null;
  288. return new Stmnt(t, expr, new ASTList(thenp, new ASTList(elsep)));
  289. }
  290. /* while.statement : WHILE "(" expression ")" statement
  291. */
  292. private Stmnt parseWhile(SymbolTable tbl)
  293. throws CompileError
  294. {
  295. int t = lex.get(); // WHILE
  296. if (lex.get() != '(')
  297. throw new SyntaxError(lex);
  298. ASTree expr = parseExpression(tbl);
  299. if (lex.get() != ')')
  300. throw new SyntaxError(lex);
  301. Stmnt body = parseStatement(tbl);
  302. return new Stmnt(t, expr, body);
  303. }
  304. /* do.statement : DO statement WHILE "(" expression ")" ";"
  305. */
  306. private Stmnt parseDo(SymbolTable tbl) throws CompileError {
  307. int t = lex.get(); // DO
  308. Stmnt body = parseStatement(tbl);
  309. if (lex.get() != WHILE || lex.get() != '(')
  310. throw new SyntaxError(lex);
  311. ASTree expr = parseExpression(tbl);
  312. if (lex.get() != ')' || lex.get() != ';')
  313. throw new SyntaxError(lex);
  314. return new Stmnt(t, expr, body);
  315. }
  316. /* for.statement : FOR "(" decl.or.expr expression ";" expression ")"
  317. * statement
  318. */
  319. private Stmnt parseFor(SymbolTable tbl) throws CompileError {
  320. Stmnt expr1, expr3;
  321. ASTree expr2;
  322. int t = lex.get(); // FOR
  323. SymbolTable tbl2 = new SymbolTable(tbl);
  324. if (lex.get() != '(')
  325. throw new SyntaxError(lex);
  326. if (lex.lookAhead() == ';') {
  327. lex.get();
  328. expr1 = null;
  329. }
  330. else
  331. expr1 = parseDeclarationOrExpression(tbl2, true);
  332. if (lex.lookAhead() == ';')
  333. expr2 = null;
  334. else
  335. expr2 = parseExpression(tbl2);
  336. if (lex.get() != ';')
  337. throw new CompileError("; is missing", lex);
  338. if (lex.lookAhead() == ')')
  339. expr3 = null;
  340. else
  341. expr3 = parseExprList(tbl2);
  342. if (lex.get() != ')')
  343. throw new CompileError(") is missing", lex);
  344. Stmnt body = parseStatement(tbl2);
  345. return new Stmnt(t, expr1, new ASTList(expr2,
  346. new ASTList(expr3, body)));
  347. }
  348. /* switch.statement : SWITCH "(" expression ")" "{" switch.block "}"
  349. *
  350. * swtich.block : ( switch.label* statement )*
  351. *
  352. * swtich.label : DEFAULT ":"
  353. * | CASE const.expression ":"
  354. */
  355. private Stmnt parseSwitch(SymbolTable tbl) throws CompileError {
  356. throw new CompileError("switch is not supported", lex);
  357. }
  358. /* synchronized.statement :
  359. * SYNCHRONIZED "(" expression ")" block.statement
  360. */
  361. private Stmnt parseSynchronized(SymbolTable tbl) throws CompileError {
  362. throw new CompileError("synchronized is not supported", lex);
  363. }
  364. /* try.statement
  365. * : TRY block.statement
  366. * [ CATCH "(" class.type Identifier ")" block.statement ]*
  367. * [ FINALLY block.statement ]*
  368. */
  369. private Stmnt parseTry(SymbolTable tbl) throws CompileError {
  370. lex.get(); // TRY
  371. Stmnt block = parseBlock(tbl);
  372. ASTList catchList = null;
  373. while (lex.lookAhead() == CATCH) {
  374. lex.get(); // CATCH
  375. if (lex.get() != '(')
  376. throw new SyntaxError(lex);
  377. SymbolTable tbl2 = new SymbolTable(tbl);
  378. Declarator d = parseFormalParam(tbl2);
  379. if (d.getArrayDim() > 0 || d.getType() != CLASS)
  380. throw new SyntaxError(lex);
  381. if (lex.get() != ')')
  382. throw new SyntaxError(lex);
  383. Stmnt b = parseBlock(tbl2);
  384. catchList = ASTList.append(catchList, new Pair(d, b));
  385. }
  386. Stmnt finallyBlock = null;
  387. if (lex.lookAhead() == FINALLY) {
  388. lex.get(); // FINALLY
  389. finallyBlock = parseBlock(tbl);
  390. }
  391. return Stmnt.make(TRY, block, catchList, finallyBlock);
  392. }
  393. /* return.statement : RETURN [ expression ] ";"
  394. */
  395. private Stmnt parseReturn(SymbolTable tbl) throws CompileError {
  396. int t = lex.get(); // RETURN
  397. Stmnt s = new Stmnt(t);
  398. if (lex.lookAhead() != ';')
  399. s.setLeft(parseExpression(tbl));
  400. if (lex.get() != ';')
  401. throw new CompileError("; is missing", lex);
  402. return s;
  403. }
  404. /* throw.statement : THROW expression ";"
  405. */
  406. private Stmnt parseThrow(SymbolTable tbl) throws CompileError {
  407. int t = lex.get(); // THROW
  408. ASTree expr = parseExpression(tbl);
  409. if (lex.get() != ';')
  410. throw new CompileError("; is missing", lex);
  411. return new Stmnt(t, expr);
  412. }
  413. /* break.statement : BREAK [ Identifier ] ";"
  414. */
  415. private Stmnt parseBreak(SymbolTable tbl)
  416. throws CompileError
  417. {
  418. return parseContinue(tbl);
  419. }
  420. /* continue.statement : CONTINUE [ Identifier ] ";"
  421. */
  422. private Stmnt parseContinue(SymbolTable tbl)
  423. throws CompileError
  424. {
  425. int t = lex.get(); // CONTINUE
  426. Stmnt s = new Stmnt(t);
  427. int t2 = lex.get();
  428. if (t2 == Identifier) {
  429. s.setLeft(new Symbol(lex.getString()));
  430. t2 = lex.get();
  431. }
  432. if (t2 != ';')
  433. throw new CompileError("; is missing", lex);
  434. return s;
  435. }
  436. /* declaration.or.expression
  437. * : [ FINAL ] built-in-type array.dimension declarators
  438. * | [ FINAL ] class.type array.dimension declarators
  439. * | expression ';'
  440. * | expr.list ';' if exprList is true
  441. *
  442. * Note: FINAL is currently ignored. This must be fixed
  443. * in future.
  444. */
  445. private Stmnt parseDeclarationOrExpression(SymbolTable tbl,
  446. boolean exprList)
  447. throws CompileError
  448. {
  449. int t = lex.lookAhead();
  450. while (t == FINAL) {
  451. lex.get();
  452. t = lex.lookAhead();
  453. }
  454. if (isBuiltinType(t)) {
  455. t = lex.get();
  456. int dim = parseArrayDimension();
  457. return parseDeclarators(tbl, new Declarator(t, dim));
  458. }
  459. else if (t == Identifier) {
  460. int i = nextIsClassType(0);
  461. if (i >= 0)
  462. if (lex.lookAhead(i) == Identifier) {
  463. ASTList name = parseClassType(tbl);
  464. int dim = parseArrayDimension();
  465. return parseDeclarators(tbl, new Declarator(name, dim));
  466. }
  467. }
  468. Stmnt expr;
  469. if (exprList)
  470. expr = parseExprList(tbl);
  471. else
  472. expr = new Stmnt(EXPR, parseExpression(tbl));
  473. if (lex.get() != ';')
  474. throw new CompileError("; is missing", lex);
  475. return expr;
  476. }
  477. /* expr.list : ( expression ',')* expression
  478. */
  479. private Stmnt parseExprList(SymbolTable tbl) throws CompileError {
  480. Stmnt expr = null;
  481. for (;;) {
  482. Stmnt e = new Stmnt(EXPR, parseExpression(tbl));
  483. expr = (Stmnt)ASTList.concat(expr, new Stmnt(BLOCK, e));
  484. if (lex.lookAhead() == ',')
  485. lex.get();
  486. else
  487. return expr;
  488. }
  489. }
  490. /* declarators : declarator [ ',' declarator ]* ';'
  491. */
  492. private Stmnt parseDeclarators(SymbolTable tbl, Declarator d)
  493. throws CompileError
  494. {
  495. Stmnt decl = null;
  496. for (;;) {
  497. decl = (Stmnt)ASTList.concat(decl,
  498. new Stmnt(DECL, parseDeclarator(tbl, d)));
  499. int t = lex.get();
  500. if (t == ';')
  501. return decl;
  502. else if (t != ',')
  503. throw new CompileError("; is missing", lex);
  504. }
  505. }
  506. /* declarator : Identifier array.dimension [ '=' initializer ]
  507. */
  508. private Declarator parseDeclarator(SymbolTable tbl, Declarator d)
  509. throws CompileError
  510. {
  511. if (lex.get() != Identifier || d.getType() == VOID)
  512. throw new SyntaxError(lex);
  513. String name = lex.getString();
  514. Symbol symbol = new Symbol(name);
  515. int dim = parseArrayDimension();
  516. ASTree init = null;
  517. if (lex.lookAhead() == '=') {
  518. lex.get();
  519. init = parseInitializer(tbl);
  520. }
  521. Declarator decl = d.make(symbol, dim, init);
  522. tbl.append(name, decl);
  523. return decl;
  524. }
  525. /* initializer : expression | array.initializer
  526. */
  527. private ASTree parseInitializer(SymbolTable tbl) throws CompileError {
  528. if (lex.lookAhead() == '{')
  529. return parseArrayInitializer(tbl);
  530. else
  531. return parseExpression(tbl);
  532. }
  533. /* array.initializer :
  534. * '{' (( array.initializer | expression ) ',')* '}'
  535. */
  536. private ASTree parseArrayInitializer(SymbolTable tbl)
  537. throws CompileError
  538. {
  539. lex.get(); // '{'
  540. throw new CompileError("array initializer is not supported", lex);
  541. }
  542. /* expression : conditional.expr
  543. * | conditional.expr assign.op expression (right-to-left)
  544. */
  545. public ASTree parseExpression(SymbolTable tbl) throws CompileError {
  546. ASTree left = parseConditionalExpr(tbl);
  547. if (!isAssignOp(lex.lookAhead()))
  548. return left;
  549. int t = lex.get();
  550. ASTree right = parseExpression(tbl);
  551. return AssignExpr.makeAssign(t, left, right);
  552. }
  553. private static boolean isAssignOp(int t) {
  554. return t == '=' || t == MOD_E || t == AND_E
  555. || t == MUL_E || t == PLUS_E || t == MINUS_E || t == DIV_E
  556. || t == EXOR_E || t == OR_E || t == LSHIFT_E
  557. || t == RSHIFT_E || t == ARSHIFT_E;
  558. }
  559. /* conditional.expr (right-to-left)
  560. * : logical.or.expr [ '?' expression ':' conditional.expr ]
  561. */
  562. private ASTree parseConditionalExpr(SymbolTable tbl) throws CompileError {
  563. ASTree cond = parseBinaryExpr(tbl);
  564. if (lex.lookAhead() == '?') {
  565. lex.get();
  566. ASTree thenExpr = parseExpression(tbl);
  567. if (lex.get() != ':')
  568. throw new CompileError(": is missing", lex);
  569. ASTree elseExpr = parseExpression(tbl);
  570. return new CondExpr(cond, thenExpr, elseExpr);
  571. }
  572. else
  573. return cond;
  574. }
  575. /* logical.or.expr 10 (operator precedence)
  576. * : logical.and.expr
  577. * | logical.or.expr OROR logical.and.expr left-to-right
  578. *
  579. * logical.and.expr 9
  580. * : inclusive.or.expr
  581. * | logical.and.expr ANDAND inclusive.or.expr
  582. *
  583. * inclusive.or.expr 8
  584. * : exclusive.or.expr
  585. * | inclusive.or.expr "|" exclusive.or.expr
  586. *
  587. * exclusive.or.expr 7
  588. * : and.expr
  589. * | exclusive.or.expr "^" and.expr
  590. *
  591. * and.expr 6
  592. * : equality.expr
  593. * | and.expr "&" equality.expr
  594. *
  595. * equality.expr 5
  596. * : relational.expr
  597. * | equality.expr (EQ | NEQ) relational.expr
  598. *
  599. * relational.expr 4
  600. * : shift.expr
  601. * | relational.expr (LE | GE | "<" | ">") shift.expr
  602. * | relational.expr INSTANCEOF class.type ("[" "]")*
  603. *
  604. * shift.expr 3
  605. * : additive.expr
  606. * | shift.expr (LSHIFT | RSHIFT | ARSHIFT) additive.expr
  607. *
  608. * additive.expr 2
  609. * : multiply.expr
  610. * | additive.expr ("+" | "-") multiply.expr
  611. *
  612. * multiply.expr 1
  613. * : unary.expr
  614. * | multiply.expr ("*" | "/" | "%") unary.expr
  615. */
  616. private ASTree parseBinaryExpr(SymbolTable tbl) throws CompileError {
  617. ASTree expr = parseUnaryExpr(tbl);
  618. for (;;) {
  619. int t = lex.lookAhead();
  620. int p = getOpPrecedence(t);
  621. if (p == 0)
  622. return expr;
  623. else
  624. expr = binaryExpr2(tbl, expr, p);
  625. }
  626. }
  627. private ASTree parseInstanceOf(SymbolTable tbl, ASTree expr)
  628. throws CompileError
  629. {
  630. int t = lex.lookAhead();
  631. if (isBuiltinType(t)) {
  632. lex.get(); // primitive type
  633. int dim = parseArrayDimension();
  634. return new InstanceOfExpr(t, dim, expr);
  635. }
  636. else {
  637. ASTList name = parseClassType(tbl);
  638. int dim = parseArrayDimension();
  639. return new InstanceOfExpr(name, dim, expr);
  640. }
  641. }
  642. private ASTree binaryExpr2(SymbolTable tbl, ASTree expr, int prec)
  643. throws CompileError
  644. {
  645. int t = lex.get();
  646. if (t == INSTANCEOF)
  647. return parseInstanceOf(tbl, expr);
  648. ASTree expr2 = parseUnaryExpr(tbl);
  649. for (;;) {
  650. int t2 = lex.lookAhead();
  651. int p2 = getOpPrecedence(t2);
  652. if (p2 != 0 && prec > p2)
  653. expr2 = binaryExpr2(tbl, expr2, p2);
  654. else
  655. return BinExpr.makeBin(t, expr, expr2);
  656. }
  657. }
  658. // !"#$%&'( )*+,-./0 12345678 9:;<=>?
  659. private static final int[] binaryOpPrecedence
  660. = { 0, 0, 0, 0, 1, 6, 0, 0,
  661. 0, 1, 2, 0, 2, 0, 1, 0,
  662. 0, 0, 0, 0, 0, 0, 0, 0,
  663. 0, 0, 0, 4, 0, 4, 0 };
  664. private int getOpPrecedence(int c) {
  665. if ('!' <= c && c <= '?')
  666. return binaryOpPrecedence[c - '!'];
  667. else if (c == '^')
  668. return 7;
  669. else if (c == '|')
  670. return 8;
  671. else if (c == ANDAND)
  672. return 9;
  673. else if (c == OROR)
  674. return 10;
  675. else if (c == EQ || c == NEQ)
  676. return 5;
  677. else if (c == LE || c == GE || c == INSTANCEOF)
  678. return 4;
  679. else if (c == LSHIFT || c == RSHIFT || c == ARSHIFT)
  680. return 3;
  681. else
  682. return 0; // not a binary operator
  683. }
  684. /* unary.expr : "++"|"--" unary.expr
  685. | "+"|"-" unary.expr
  686. | "!"|"~" unary.expr
  687. | cast.expr
  688. | postfix.expr
  689. unary.expr.not.plus.minus is a unary expression starting without
  690. "+", "-", "++", or "--".
  691. */
  692. private ASTree parseUnaryExpr(SymbolTable tbl) throws CompileError {
  693. int t;
  694. switch (lex.lookAhead()) {
  695. case '+' :
  696. case '-' :
  697. case PLUSPLUS :
  698. case MINUSMINUS :
  699. case '!' :
  700. case '~' :
  701. t = lex.get();
  702. return new Expr(t, parseUnaryExpr(tbl));
  703. case '(' :
  704. return parseCast(tbl);
  705. default :
  706. return parsePostfix(tbl);
  707. }
  708. }
  709. /* cast.expr : "(" builtin.type ("[" "]")* ")" unary.expr
  710. | "(" class.type ("[" "]")* ")" unary.expr2
  711. unary.expr2 is a unary.expr begining with "(", NULL, StringL,
  712. Identifier, THIS, SUPER, or NEW.
  713. */
  714. private ASTree parseCast(SymbolTable tbl) throws CompileError {
  715. int t = lex.lookAhead(1);
  716. if (isBuiltinType(t)) {
  717. lex.get(); // '('
  718. lex.get(); // primitive type
  719. int dim = parseArrayDimension();
  720. if (lex.get() != ')')
  721. throw new CompileError(") is missing", lex);
  722. return new CastExpr(t, dim, parseUnaryExpr(tbl));
  723. }
  724. else if (t == Identifier && nextIsClassCast()) {
  725. lex.get(); // '('
  726. ASTList name = parseClassType(tbl);
  727. int dim = parseArrayDimension();
  728. if (lex.get() != ')')
  729. throw new CompileError(") is missing", lex);
  730. return new CastExpr(name, dim, parseUnaryExpr(tbl));
  731. }
  732. else
  733. return parsePostfix(tbl);
  734. }
  735. private boolean nextIsClassCast() {
  736. int i = nextIsClassType(1);
  737. if (i < 0)
  738. return false;
  739. int t = lex.lookAhead(i);
  740. if (t != ')')
  741. return false;
  742. t = lex.lookAhead(i + 1);
  743. return t == '(' || t == NULL || t == StringL
  744. || t == Identifier || t == THIS || t == SUPER || t == NEW
  745. || t == TRUE || t == FALSE || t == LongConstant
  746. || t == IntConstant || t == CharConstant
  747. || t == DoubleConstant || t == FloatConstant;
  748. }
  749. private int nextIsClassType(int i) {
  750. int t;
  751. while (lex.lookAhead(++i) == '.')
  752. if (lex.lookAhead(++i) != Identifier)
  753. return -1;
  754. while ((t = lex.lookAhead(i++)) == '[')
  755. if (lex.lookAhead(i++) != ']')
  756. return -1;
  757. return i - 1;
  758. }
  759. /* array.dimension : [ "[" "]" ]*
  760. */
  761. private int parseArrayDimension() throws CompileError {
  762. int arrayDim = 0;
  763. while (lex.lookAhead() == '[') {
  764. ++arrayDim;
  765. lex.get();
  766. if (lex.get() != ']')
  767. throw new CompileError("] is missing", lex);
  768. }
  769. return arrayDim;
  770. }
  771. /* class.type : Identifier ( "." Identifier )*
  772. */
  773. private ASTList parseClassType(SymbolTable tbl) throws CompileError {
  774. ASTList list = null;
  775. for (;;) {
  776. if (lex.get() != Identifier)
  777. throw new SyntaxError(lex);
  778. list = ASTList.append(list, new Symbol(lex.getString()));
  779. if (lex.lookAhead() == '.')
  780. lex.get();
  781. else
  782. break;
  783. }
  784. return list;
  785. }
  786. /* postfix.expr : number.literal
  787. * | primary.expr
  788. * | method.expr
  789. * | postfix.expr "++" | "--"
  790. * | postfix.expr "[" array.size "]"
  791. * | postfix.expr "." Identifier
  792. * | postfix.expr "#" Identifier
  793. *
  794. * "#" is not an operator of regular Java. It separates
  795. * a class name and a member name in an expression for static member
  796. * access. For example,
  797. * java.lang.Integer.toString(3) in regular Java
  798. * must be written like this:
  799. * java.lang.Integer#toString(3) for this compiler.
  800. */
  801. private ASTree parsePostfix(SymbolTable tbl) throws CompileError {
  802. int token = lex.lookAhead();
  803. switch (token) {
  804. case LongConstant :
  805. case IntConstant :
  806. case CharConstant :
  807. lex.get();
  808. return new IntConst(lex.getLong(), token);
  809. case DoubleConstant :
  810. case FloatConstant :
  811. lex.get();
  812. return new DoubleConst(lex.getDouble(), token);
  813. default :
  814. break;
  815. }
  816. String str;
  817. ASTree index;
  818. ASTree expr = parsePrimaryExpr(tbl);
  819. int t;
  820. while (true) {
  821. switch (lex.lookAhead()) {
  822. case '(' :
  823. expr = parseMethodCall(tbl, expr);
  824. break;
  825. case '[' :
  826. index = parseArrayIndex(tbl);
  827. if (index == null)
  828. throw new SyntaxError(lex);
  829. expr = Expr.make(ARRAY, expr, index);
  830. break;
  831. case PLUSPLUS :
  832. case MINUSMINUS :
  833. t = lex.get();
  834. expr = Expr.make(t, null, expr);
  835. break;
  836. case '.' :
  837. lex.get();
  838. if (lex.get() != Identifier)
  839. throw new CompileError("missing member name", lex);
  840. expr = Expr.make('.', expr, new Member(lex.getString()));
  841. break;
  842. case '#' :
  843. lex.get();
  844. t = lex.get();
  845. if (t == CLASS)
  846. str = "class";
  847. else if (t == Identifier)
  848. str = lex.getString();
  849. else
  850. throw new CompileError("missing static member name", lex);
  851. expr = Expr.make(MEMBER, toClassName(expr, null),
  852. new Member(str));
  853. break;
  854. default :
  855. return expr;
  856. }
  857. }
  858. }
  859. /* method.call : method.expr "(" argument.list ")"
  860. * method.expr : THIS | SUPER | Identifier
  861. * | postfix.expr "." Identifier
  862. * | postfix.expr "#" Identifier
  863. */
  864. private ASTree parseMethodCall(SymbolTable tbl, ASTree expr)
  865. throws CompileError
  866. {
  867. if (expr instanceof Keyword) {
  868. int token = ((Keyword)expr).get();
  869. if (token != THIS && token != SUPER)
  870. throw new SyntaxError(lex);
  871. }
  872. else if (expr instanceof Symbol) // Identifier
  873. ;
  874. else if (expr instanceof Expr) {
  875. int op = ((Expr)expr).getOperator();
  876. if (op != '.' && op != MEMBER)
  877. throw new SyntaxError(lex);
  878. }
  879. return Expr.make(CALL, expr, parseArgumentList(tbl));
  880. }
  881. private ASTList toClassName(ASTree name, ASTList tail)
  882. throws CompileError
  883. {
  884. if (name instanceof Symbol)
  885. return new ASTList(name, tail);
  886. else if (name instanceof Expr) {
  887. Expr expr = (Expr)name;
  888. if (expr.getOperator() == '.')
  889. return toClassName(expr.oprand1(),
  890. new ASTList(expr.oprand2(), tail));
  891. }
  892. throw new CompileError("bad static member access", lex);
  893. }
  894. /* primary.expr : THIS | SUPER | TRUE | FALSE | NULL
  895. * | StringL
  896. * | Identifier
  897. * | NEW new.expr
  898. * | "(" expression ")"
  899. *
  900. * Identifier represents either a local variable name, a member name,
  901. * or a class name.
  902. */
  903. private ASTree parsePrimaryExpr(SymbolTable tbl) throws CompileError {
  904. int t;
  905. String name;
  906. Declarator decl;
  907. ASTree expr;
  908. switch (t = lex.get()) {
  909. case THIS :
  910. case SUPER :
  911. case TRUE :
  912. case FALSE :
  913. case NULL :
  914. return new Keyword(t);
  915. case Identifier :
  916. name = lex.getString();
  917. decl = tbl.lookup(name);
  918. if (decl == null)
  919. return new Member(name); // this or static member
  920. else
  921. return new Variable(name, decl); // local variable
  922. case StringL :
  923. return new StringL(lex.getString());
  924. case NEW :
  925. return parseNew(tbl);
  926. case '(' :
  927. expr = parseExpression(tbl);
  928. if (lex.get() == ')')
  929. return expr;
  930. else
  931. throw new CompileError(") is missing", lex);
  932. default :
  933. throw new SyntaxError(lex);
  934. }
  935. }
  936. /* new.expr : class.type "(" argument.list ")"
  937. * | class.type array.size [ array.initializer ]
  938. * | primitive.type array.size [ array.initializer ]
  939. */
  940. private NewExpr parseNew(SymbolTable tbl) throws CompileError {
  941. ASTree init = null;
  942. int t = lex.lookAhead();
  943. if (isBuiltinType(t)) {
  944. lex.get();
  945. ASTList size = parseArraySize(tbl);
  946. if (lex.lookAhead() == '{')
  947. init = parseArrayInitializer(tbl);
  948. return new NewExpr(t, size, init);
  949. }
  950. else if (t == Identifier) {
  951. ASTList name = parseClassType(tbl);
  952. t = lex.lookAhead();
  953. if (t == '(') {
  954. ASTList args = parseArgumentList(tbl);
  955. return new NewExpr(name, args);
  956. }
  957. else if (t == '[') {
  958. ASTList size = parseArraySize(tbl);
  959. if (lex.lookAhead() == '{')
  960. init = parseArrayInitializer(tbl);
  961. return NewExpr.makeObjectArray(name, size, init);
  962. }
  963. }
  964. throw new SyntaxError(lex);
  965. }
  966. /* array.size : [ array.index ]*
  967. */
  968. private ASTList parseArraySize(SymbolTable tbl) throws CompileError {
  969. ASTList list = null;
  970. while (lex.lookAhead() == '[')
  971. list = ASTList.append(list, parseArrayIndex(tbl));
  972. return list;
  973. }
  974. /* array.index : "[" [ expression ] "]"
  975. */
  976. private ASTree parseArrayIndex(SymbolTable tbl) throws CompileError {
  977. lex.get(); // '['
  978. if (lex.lookAhead() == ']') {
  979. lex.get();
  980. return null;
  981. }
  982. else {
  983. ASTree index = parseExpression(tbl);
  984. if (lex.get() != ']')
  985. throw new CompileError("] is missing", lex);
  986. return index;
  987. }
  988. }
  989. /* argument.list : "(" [ expression [ "," expression ]* ] ")"
  990. */
  991. private ASTList parseArgumentList(SymbolTable tbl) throws CompileError {
  992. if (lex.get() != '(')
  993. throw new CompileError("( is missing", lex);
  994. ASTList list = null;
  995. if (lex.lookAhead() != ')')
  996. for (;;) {
  997. list = ASTList.append(list, parseExpression(tbl));
  998. if (lex.lookAhead() == ',')
  999. lex.get();
  1000. else
  1001. break;
  1002. }
  1003. if (lex.get() != ')')
  1004. throw new CompileError(") is missing", lex);
  1005. return list;
  1006. }
  1007. }