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

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