Advertisement
Guest User

Untitled

a guest
Mar 24th, 2017
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.63 KB | None | 0 0
  1. package lab3.autogen;
  2. import lab3.*;
  3. import java_cup.runtime.*;
  4.  
  5. import java.util.Vector;
  6. import java.util.Enumeration;
  7.  
  8. // $Id: jmm.cup 33 2010-08-09 21:47:19Z cytron $
  9.  
  10. /*
  11. * Java minus minus grammar
  12. *
  13. */
  14.  
  15. /*
  16. * This is a standard Java grammar, modified for our use. Many features
  17. * are noted as "extra credit". You must negotiate
  18. * the extra credit with the professor.
  19. *
  20. * Some features are added too: look for comments to that effect.
  21. * RC
  22. */
  23.  
  24. action code {:
  25.  
  26. /** Code that is included with the action blocks
  27. *
  28. */
  29.  
  30. /* Need some classes that extend AbstractNode? Here's an example */
  31. /* The TemporaryNode is just a place holder, and is good for development but
  32. * should eventually go away.
  33. */
  34.  
  35. class Example extends AbstractNode {
  36. public String getName() { return "Example"; }
  37. }
  38.  
  39. class TemporaryNode extends AbstractNode {
  40.  
  41. private String s;
  42.  
  43. public TemporaryNode(String s) {
  44. this.s = s;
  45. }
  46.  
  47. public String getName() { return s; }
  48.  
  49. }
  50.  
  51. class IntegerNode extends AbstractNode {
  52. private Integer val;
  53. public IntegerNode(Integer val) { this.val = val; }
  54. public String getName() { return "Integer " + val; }
  55. }
  56.  
  57. /* Factory methods to make nodes
  58. * Add ones here that make it easy for you.
  59. The ones given here are temporary placeholders
  60. */
  61.  
  62. public AbstractNode makeNode(Symbol s) { return new TemporaryNode(symString.symToString[s.sym]); }
  63. public AbstractNode makeNode(String s) { return new TemporaryNode(s); }
  64. public AbstractNode makeNode(Integer i) { return new IntegerNode(i); }
  65.  
  66.  
  67. :};
  68.  
  69. /*
  70. * Almost all of these can just be Symbol types, used for parsing. Occasionally,
  71. * a terminal has semantic information of use, as was the case for number in hw2.
  72. * In those cases, declare the Symbol appropriately but you'll have to modify the
  73. * Scanner to return the right type. I've done this for integer and string types below
  74. */
  75.  
  76. terminal Symbol OP_GE, OP_LE, OP_EQ, OP_NE, OP_GT, OP_LT;
  77. terminal Symbol OP_LAND, OP_LOR;
  78. terminal Symbol INSTANCEOF;
  79. terminal Symbol HAT, TILDE;
  80. terminal Symbol BOOLEAN;
  81. terminal Symbol CLASS;
  82. terminal Symbol ELSE;
  83. terminal Symbol IF, INT;
  84. terminal Symbol NEW, NULL;
  85. terminal Symbol PRIVATE, PUBLIC;
  86. terminal Symbol RETURN;
  87. terminal Symbol STATIC, SUPER;
  88. terminal Symbol THIS;
  89. terminal Symbol VOID;
  90. terminal Symbol WHILE;
  91. terminal Symbol ASS_ADD;
  92. terminal Symbol LPAREN, RPAREN, LBRACE, RBRACE, EQUALS;
  93. terminal Symbol PERIOD, COLON, SEMICOLON, COMMA, PIPE, AND, ASTERICK;
  94. terminal Symbol PLUSOP, MINUSOP, RSLASH, PERCENT, QUESTION;
  95. terminal Symbol BANG;
  96.  
  97. terminal String IDENTIFIER, LITERAL;
  98. terminal Integer INTNUMBER;
  99.  
  100.  
  101. /* To save you typing, I've made all these AbstracNode types. You will want
  102. * to customize them as you go.
  103. */
  104.  
  105. non terminal AbstractNode CompilationUnit;
  106. non terminal AbstractNode FieldVariableDeclaration;
  107. non terminal AbstractNode MethodDeclaration;
  108. non terminal AbstractNode MethodDeclarator;
  109. non terminal AbstractNode ParameterList, Parameter;
  110. non terminal AbstractNode MethodBody, ConstructorDeclaration;
  111. non terminal AbstractNode StaticInitializer;
  112. non terminal AbstractNode Block;
  113. non terminal AbstractNode LocalVariableDeclarationsAndStatements;
  114. non terminal AbstractNode LocalVariableDeclarationOrStatement;
  115. non terminal AbstractNode LocalVariableDeclarationStatement ;
  116. non terminal AbstractNode Statement, EmptyStatement;
  117. non terminal AbstractNode MatchedStatement, UnMatchedStatement;
  118. non terminal AbstractNode ExpressionStatement;
  119. non terminal AbstractNode MatchedSelectionStatement, UnMatchedSelectionStatement;
  120. non terminal AbstractNode MatchedIterationStatement, UnMatchedIterationStatement;
  121. non terminal AbstractNode PrimaryExpression;
  122. non terminal AbstractNode NotJustName, ComplexPrimary, ComplexPrimaryNoParenthesis;
  123. non terminal AbstractNode FieldAccess, MethodCall, MethodReference;
  124. non terminal AbstractNode SpecialName, ArgumentList, AllocationExpression;
  125. non terminal AbstractNode PostfixExpression;
  126. non terminal AbstractNode UnaryExpression, LogicalUnaryExpression;
  127. non terminal AbstractNode LogicalUnaryOperator, ArithmeticUnaryOperator;
  128. non terminal AbstractNode CastExpression, MultiplicativeExpression;
  129. non terminal AbstractNode AdditiveExpression, ShiftExpression, RelationalExpression;
  130. non terminal AbstractNode EqualityExpression, AndExpression, ExclusiveOrExpression;
  131. non terminal AbstractNode InclusiveOrExpression, ConditionalAndExpression;
  132. non terminal AbstractNode ConditionalOrExpression;
  133. non terminal AbstractNode ConditionalExpression, AssignmentExpression;
  134. non terminal AbstractNode AssignmentOperator;
  135. non terminal AbstractNode Expression;
  136. non terminal AbstractNode ReturnStatement;
  137.  
  138. non terminal AbstractNode Identifier;
  139. non terminal AbstractNode Literal;
  140. non terminal AbstractNode Number;
  141. non terminal AbstractNode DeclaratorName;
  142. non terminal AbstractNode FieldVariableDeclaratorName;
  143. non terminal AbstractNode MethodDeclaratorName;
  144. non terminal AbstractNode LocalVariableDeclaratorName;
  145. non terminal AbstractNode TypeDeclarations;
  146. non terminal AbstractNode TypeDeclaration;
  147. non terminal AbstractNode ClassDeclaration;
  148. non terminal AbstractNode ClassBody;
  149. non terminal AbstractNode Modifiers;
  150. non terminal AbstractNode FieldDeclarations;
  151. non terminal AbstractNode FieldDeclaration;
  152. non terminal AbstractNode FieldVariableDeclarators;
  153. non terminal AbstractNode LocalVariableDeclarators;
  154. non terminal AbstractNode QualifiedName;
  155. non terminal AbstractNode TypeName, TypeSpecifier;
  156. non terminal AbstractNode PrimitiveType;
  157.  
  158. start with CompilationUnit;
  159.  
  160.  
  161. CompilationUnit
  162. ::= TypeDeclarations:td
  163. {:
  164. AbstractNode prog = makeNode("Program").adoptChildren(td);
  165.  
  166. System.out.println("\n\n");
  167. prog.walkTree(new PrintTree(System.out));
  168. :}
  169. ;
  170.  
  171. /*
  172. * Simple node magic to link nodes together as siblings. Covered
  173. * in class -- you have to be aware of how the list is growing
  174. * These children will be adopted by CompilationUnit rule above.
  175. */
  176.  
  177. TypeDeclarations
  178. ::= TypeDeclaration:td
  179. {: RESULT = td; :}
  180. | TypeDeclarations:tds TypeDeclaration:td
  181. {: RESULT = tds.makeSibling(td); :}
  182. ;
  183.  
  184. /*
  185. * Extra credit: interfaces, but classes are all we'll deal with by default
  186. */
  187. TypeDeclaration
  188. ::= ClassDeclaration:rhs
  189. {:
  190. RESULT = rhs;
  191. :}
  192. ;
  193.  
  194.  
  195. ClassDeclaration
  196. ::= Modifiers:mods CLASS:cl Identifier:id ClassBody:clb
  197. {:
  198. RESULT = makeNode("Declaration of " + mods + " Class " + id).adoptChildren(clb);
  199. :}
  200. ;
  201.  
  202. /*
  203. * Process bottom-up to figure out whether the Modifier
  204. * is static or not
  205. * is public or not
  206. * A pair of booleans, like IntPair could be used, or IntPair could be used
  207. * if you know what I mean.
  208. */
  209. Modifiers
  210. ::= PUBLIC
  211. {: RESULT = makeNode("Public"); :}
  212. | PRIVATE
  213. {: RESULT = makeNode("Private"); :}
  214. | STATIC
  215. {: RESULT = makeNode("Static"); :}
  216. | Modifiers:mds PUBLIC
  217. {: RESULT = makeNode("Public " + mds); :}
  218. | Modifiers:mds PRIVATE
  219. {: RESULT = makeNode("Private " + mds); :}
  220. | Modifiers:mds STATIC
  221. {: RESULT = makeNode("Static" + mds); :}
  222. ;
  223.  
  224.  
  225. /*
  226. * Extra credit: other types
  227. */
  228. PrimitiveType
  229. ::= BOOLEAN:tok
  230. {: RESULT = makeNode(tok); :}
  231. | INT:tok
  232. {: RESULT = makeNode(tok); :}
  233. | VOID:tok
  234. {: RESULT = makeNode(tok); :}
  235. ;
  236.  
  237. /*
  238. * You need a nice structure to represent this list of identifiers.
  239. * You might consider java.util.Vector
  240. */
  241. QualifiedName
  242. ::= Identifier:id
  243. {: RESULT = id;:}
  244. | QualifiedName:qn PERIOD Identifier:id
  245. {: RESULT = makeNode(qn.getName() + "/" +id.getName()); :}
  246. ;
  247.  
  248. /*
  249. * In a given program, FieldDeclarations can occur in any order.
  250. * But we would like them grouped together.
  251. * So, structure your AST so that the items coming back from
  252. * FieldDeclarations are grouped by:
  253. *
  254. * fields, statics, constructors, methods, inner classes
  255. *
  256. * (run the class solution if confused)
  257. */
  258. ClassBody
  259. ::= LBRACE FieldDeclarations:fds RBRACE
  260. {:
  261. RESULT = makeNode("BODY:").adoptChildren(fds);
  262. :}
  263. | LBRACE RBRACE
  264. ;
  265.  
  266. FieldDeclarations
  267. ::= FieldDeclaration:fd
  268. {: RESULT = fd; :}
  269. | FieldDeclarations:fds FieldDeclaration:fd
  270. {: RESULT = fds.makeSibling(fd); :}
  271. ;
  272.  
  273. FieldDeclaration
  274. ::= FieldVariableDeclaration:fvd SEMICOLON
  275. {: RESULT = makeNode("FIELD: ").adoptChildren(fvd); :}
  276. | MethodDeclaration:rhs'
  277. {: RESULT = makeNode("METHOD: ").adoptChildren(rhs); :}
  278. | ConstructorDeclaration:rhs
  279. {: RESULT = makeNode("CONSTRUCTOR: ").adoptChildren(rhs); :}
  280. | StaticInitializer:rhs
  281. {: RESULT = makeNode("STATIC: ").adoptChildren(rhs); :}
  282. | ClassDeclaration
  283. {: RESULT = makeNode("INNER CLASS: "); :}
  284. ;
  285.  
  286. /*
  287. * This isn't structured so nicely for a bottom up parse. Recall
  288. * the example I did in class for Digits, where the "type" of the digits
  289. * (i.e., the base) is sitting off to the side. You'll have to do something
  290. * here to get the information where you want it, so that the declarations can
  291. * be suitably annotated with their type and modifier information.
  292. */
  293. FieldVariableDeclaration
  294. ::= Modifiers:m TypeSpecifier:t FieldVariableDeclarators:fvds
  295. {: RESULT = makeNode(String.format("%s %s", m, t)).adoptChildren(fvds); :}
  296. ;
  297.  
  298. TypeSpecifier
  299. ::= TypeName:rhs
  300. {: RESULT = rhs; :}
  301. ;
  302.  
  303. TypeName
  304. ::= PrimitiveType:rhs
  305. {: RESULT = rhs; :}
  306. | QualifiedName:rhs
  307. {: RESULT = rhs; :}
  308. ;
  309.  
  310. FieldVariableDeclarators
  311. ::= FieldVariableDeclaratorName:v
  312. {: RESULT = v; :}
  313. | FieldVariableDeclarators:fds COMMA FieldVariableDeclaratorName:v
  314. {: RESULT = fds.makeSibling(v); :}
  315. ;
  316.  
  317. /*
  318. * We require modifiers, extra credit for package stuff
  319. */
  320. MethodDeclaration
  321. ::= Modifiers:m TypeSpecifier:t MethodDeclarator:md MethodBody:rhs
  322. {:
  323. AbstractNode method = makeNode(m + " " + t + " " + md.getName());
  324. AbstractNode params = makeNode("PARAMS: ").adoptChildren(md);
  325. method.adoptChildren(params);
  326. method.adoptChildren(rhs);
  327. RESULT = method;
  328. :}
  329. ;
  330.  
  331. MethodDeclarator
  332. ::= MethodDeclaratorName:dn LPAREN ParameterList:pl RPAREN
  333. {: RESULT = dn.adoptChildren(pl); :}
  334. | MethodDeclaratorName:dn LPAREN RPAREN
  335. {: RESULT = dn; :}
  336. ;
  337.  
  338. ParameterList
  339. ::= Parameter:rhs
  340. {: RESULT = rhs; :}
  341. | ParameterList:spine COMMA Parameter:rhs
  342. {: RESULT = spine.makeSibling(rhs); :}
  343. ;
  344.  
  345. Parameter
  346. ::= TypeSpecifier:t DeclaratorName:dn
  347. {: RESULT = makeNode("PARAM: " + t + " " + dn); :}
  348. ;
  349.  
  350. DeclaratorName
  351. ::= Identifier:in
  352. {: RESULT = in; :}
  353. ;
  354.  
  355. MethodDeclaratorName
  356. ::= Identifier:in
  357. {: RESULT = in; :}
  358. ;
  359.  
  360. FieldVariableDeclaratorName
  361. ::= Identifier:in
  362. {: RESULT = in; :}
  363. ;
  364.  
  365. LocalVariableDeclaratorName
  366. ::= Identifier:in
  367. {: RESULT = in; :}
  368. ;
  369.  
  370. MethodBody
  371. ::= Block:rhs
  372. {: RESULT = rhs; :}
  373. ;
  374.  
  375. ConstructorDeclaration
  376. ::= Modifiers:m MethodDeclarator:md Block:rhs
  377. {: AbstractNode type = m;
  378. AbstractNode paramBlock = md.adoptChildren(rhs);
  379. RESULT = type.adoptChildren(paramBlock);
  380. :}
  381. ;
  382.  
  383. StaticInitializer
  384. ::= STATIC Block:rhs
  385. {: RESULT = rhs; :}
  386. ;
  387.  
  388. /*
  389. * These can't be reorganized, because the order matters.
  390. * For example: int i; i = 5; int j = i;
  391. */
  392. Block
  393. ::= LBRACE LocalVariableDeclarationsAndStatements:stmts RBRACE
  394. {: RESULT = makeNode("BLOCK: ").adoptChildren(stmts); :}
  395. | LBRACE RBRACE
  396. ;
  397.  
  398. LocalVariableDeclarationsAndStatements
  399. ::= LocalVariableDeclarationOrStatement:rhs
  400. {: RESULT = rhs; :}
  401. | LocalVariableDeclarationsAndStatements:lvds
  402. LocalVariableDeclarationOrStatement:rhs
  403. {: RESULT = lvds.makeSibling(rhs); :}
  404. ;
  405.  
  406. LocalVariableDeclarationOrStatement
  407. ::= LocalVariableDeclarationStatement:rhs
  408. {: RESULT = rhs; :}
  409. | Statement:rhs
  410. {: RESULT = rhs; :}
  411. ;
  412.  
  413. LocalVariableDeclarationStatement
  414. ::= TypeSpecifier:t LocalVariableDeclarators:rhs SEMICOLON
  415. {: RESULT = makeNode("LOCAL " + t + ":").adoptChildren(rhs); :}
  416. | ClassDeclaration /* Inner classes */
  417. ;
  418.  
  419. LocalVariableDeclarators
  420. ::= LocalVariableDeclaratorName:v
  421. {: RESULT = v; :}
  422. | LocalVariableDeclarators:fds COMMA LocalVariableDeclaratorName:v
  423. {: RESULT = fds.makeSibling(v); :}
  424. ;
  425.  
  426. Statement
  427. ::= MatchedStatement:ms
  428. {: RESULT = ms; :}
  429. | UnMatchedStatement:us
  430. {: RESULT = us; :}
  431. ;
  432.  
  433. UnMatchedStatement
  434. ::= UnMatchedSelectionStatement
  435. {: RESULT = makeNode("_USS"); :}
  436. | UnMatchedIterationStatement
  437. {: RESULT = makeNode("_UIS"); :}
  438. ;
  439.  
  440. MatchedStatement
  441. ::= EmptyStatement:es
  442. {: RESULT = es; :}
  443. | ExpressionStatement:rhs SEMICOLON
  444. {: RESULT = rhs; :}
  445. | MatchedSelectionStatement:mss
  446. {: RESULT = makeNode("IF: ").adoptChildren(mss); :}
  447. | MatchedIterationStatement:mis
  448. {: RESULT = makeNode("WHILE: ").adoptChildren(mis); :}
  449. | ReturnStatement:rs
  450. {: RESULT = makeNode("RETURN: ").adoptChildren(rs); :}
  451. | Block:rhs
  452. {: RESULT = rhs; :}
  453. ;
  454.  
  455. EmptyStatement
  456. ::= SEMICOLON
  457. {: RESULT = makeNode("Empty Statement"); :}
  458.  
  459. ;
  460.  
  461. ExpressionStatement
  462. ::= Expression:rhs
  463. {:RESULT = rhs; :}
  464. ;
  465.  
  466. /*
  467. * You will eventually have to address the shift/reduce error that
  468. * occurs when the second IF-rule is uncommented.
  469. *
  470. */
  471.  
  472. MatchedSelectionStatement
  473. ::= IF LPAREN Expression:exp RPAREN MatchedStatement:ms ELSE MatchedStatement:rhs
  474. {:
  475. AbstractNode cond = makeNode("CONDITION: ").adoptChildren(exp);
  476. AbstractNode block = makeNode("BLOCK: ").adoptChildren(ms);
  477. AbstractNode other = makeNode("ELSE: ").adoptChildren(rhs);
  478. RESULT = cond.makeSibling(block).makeSibling(other);
  479. :}
  480. ;
  481.  
  482. UnMatchedSelectionStatement
  483. ::= IF LPAREN Expression RPAREN MatchedStatement ELSE UnMatchedStatement
  484. | IF LPAREN Expression RPAREN Statement
  485. ;
  486.  
  487. /*
  488. * Extra Credit: FOR statement, DO statement
  489. */
  490. MatchedIterationStatement
  491. ::= WHILE LPAREN Expression:exp RPAREN MatchedStatement:rhs
  492. {:
  493. AbstractNode cond = makeNode("CONDITION: ").adoptChildren(exp);
  494. AbstractNode block = makeNode("BLOCK: ").adoptChildren(rhs);
  495. RESULT = cond.makeSibling(block);
  496. :}
  497. ;
  498.  
  499. UnMatchedIterationStatement
  500. ::= WHILE LPAREN Expression RPAREN UnMatchedStatement
  501. ;
  502.  
  503. ReturnStatement
  504. ::= RETURN Expression:exp SEMICOLON
  505. {: RESULT = exp; :}
  506. | RETURN SEMICOLON
  507. ;
  508.  
  509. PrimaryExpression
  510. ::= QualifiedName:t
  511. {: RESULT = t; :}
  512. | NotJustName:rhs
  513. {: RESULT = rhs; :}
  514. /*
  515. * You will eventually have to explain the conflicts that arise when the rule below
  516. * is uncommented.
  517. * This rule lets a block ( { .... } ) serve anywhere a primary expression could.
  518. * So you could write a = { while (h>5) h = h -k; };
  519. *
  520. * | Block:rhs
  521. */
  522. ;
  523.  
  524. NotJustName
  525. ::= SpecialName:sn
  526. {: RESULT = sn; :}
  527. | AllocationExpression:ae
  528. {: RESULT = makeNode("ALLOCATION: ").adoptChildren(ae); :}
  529. | ComplexPrimary:rhs
  530. {: RESULT = rhs; :}
  531.  
  532. ;
  533.  
  534. ComplexPrimary
  535. ::= LPAREN Expression:rhs RPAREN
  536. {: RESULT = rhs; :}
  537. | ComplexPrimaryNoParenthesis:rhs
  538. {: RESULT = rhs; :}
  539. ;
  540.  
  541. ComplexPrimaryNoParenthesis
  542. ::= Literal:rhs
  543. {: RESULT = rhs; :}
  544. | Number:rhs
  545. {: RESULT = rhs; :}
  546. | FieldAccess:fa
  547. {: RESULT = makeNode("_FA"); :}
  548. | MethodCall:mc
  549. {: RESULT = makeNode("_METHOD CALL"); :}
  550. ;
  551.  
  552. FieldAccess
  553. ::= NotJustName PERIOD Identifier
  554. ;
  555.  
  556.  
  557. MethodCall
  558. ::= MethodReference LPAREN ArgumentList RPAREN
  559. | MethodReference LPAREN RPAREN
  560. ;
  561.  
  562. MethodReference
  563. ::= ComplexPrimaryNoParenthesis
  564. | QualifiedName
  565. | SpecialName
  566. ;
  567.  
  568. SpecialName
  569. ::= THIS
  570. {: RESULT = makeNode("THIS"); :}
  571. | NULL
  572. {: RESULT = makeNode("NULL"); :}
  573. | SUPER
  574. {: RESULT = makeNode("SUPER"); :}
  575. ;
  576.  
  577. ArgumentList
  578. ::= Expression
  579. | ArgumentList COMMA Expression
  580. ;
  581.  
  582. /*
  583. * Extra credit: anonymous subclasses
  584. */
  585. AllocationExpression
  586. ::= NEW TypeName:t LPAREN ArgumentList:al RPAREN
  587. {: RESULT = makeNode("_ARGLIST"); :}
  588. | NEW TypeName:t LPAREN RPAREN
  589. {: RESULT = t; :}
  590. ;
  591.  
  592. /*
  593. * Extra credit, add post increment and decrement
  594. */
  595. PostfixExpression
  596. ::= PrimaryExpression:rhs
  597. {: RESULT = rhs; :}
  598. ;
  599.  
  600. Expression
  601. ::= AssignmentExpression:rhs
  602. {: RESULT = rhs; :}
  603. ;
  604.  
  605. /*
  606. * Here we go. Following are a bunch of rules to handle the right priority and
  607. * associativity of operators. These rules can be treated fairly uniformly
  608. * for now
  609. * However, be aware that down the road, you will want subclassees that
  610. * can distinguish
  611. * the nodes by type, so that you can generate different code for
  612. * plus vs. minus, for example.
  613. */
  614.  
  615. /*
  616. * What kind of associativity do we get for assignment expressions - why?
  617. */
  618.  
  619. AssignmentExpression
  620. ::= ConditionalExpression:rhs
  621. {: RESULT = rhs; :}
  622. | UnaryExpression:lhs AssignmentOperator:op AssignmentExpression:rhs
  623. {: RESULT = makeNode(op + ": ").adoptChildren(lhs).adoptChildren(rhs); :}
  624. ;
  625.  
  626. AssignmentOperator
  627. ::= EQUALS:tok
  628. {: RESULT = makeNode("ASSIGNMENT"); :}
  629. | ASS_ADD:tok /* There are more of these if you're interested */
  630. {: RESULT = makeNode("ASSIGNMENT ADD"); :}
  631. ;
  632.  
  633. ConditionalExpression
  634. ::= ConditionalOrExpression:coe
  635. {: RESULT = coe; :}
  636. | ConditionalOrExpression QUESTION Expression COLON ConditionalExpression
  637. {: RESULT = makeNode("Ternary"); :}
  638. ;
  639.  
  640. ConditionalOrExpression
  641. ::= ConditionalAndExpression:cae
  642. {: RESULT = cae; :}
  643. | ConditionalOrExpression:left OP_LOR:op ConditionalAndExpression:right /* short-circuit OR */
  644. {: RESULT = makeNode("LOR"); :}
  645. ;
  646.  
  647. ConditionalAndExpression
  648. ::= InclusiveOrExpression:rhs
  649. {: RESULT = rhs; :}
  650. | ConditionalAndExpression:left OP_LAND:op InclusiveOrExpression:right /* short-circuit AND */
  651. {: RESULT = makeNode("LAND"); :}
  652. ;
  653.  
  654. InclusiveOrExpression
  655. ::= ExclusiveOrExpression:rhs
  656. {: RESULT = rhs; :}
  657. | InclusiveOrExpression:left PIPE:op ExclusiveOrExpression:right
  658. {: RESULT = makeNode("|"); :}
  659. ;
  660.  
  661. ExclusiveOrExpression
  662. ::= AndExpression:rhs
  663. {: RESULT = rhs; :}
  664. | ExclusiveOrExpression:left HAT:op AndExpression:right
  665. {: RESULT = makeNode("^"); :}
  666. ;
  667.  
  668. AndExpression
  669. ::= EqualityExpression:rhs
  670. {: RESULT = rhs; :}
  671. | AndExpression:left AND:op EqualityExpression:right
  672. {: RESULT = makeNode("AND"); :}
  673. ;
  674.  
  675. EqualityExpression
  676. ::= RelationalExpression:rhs
  677. {: RESULT = rhs; :}
  678. | EqualityExpression:left OP_EQ:op RelationalExpression:right
  679. {: RESULT = makeNode("EQ"); :}
  680. | EqualityExpression:left OP_NE:op RelationalExpression:right
  681. {: RESULT = makeNode("NE"); :}
  682. ;
  683.  
  684. RelationalExpression
  685. ::= ShiftExpression:rhs
  686. {: RESULT = rhs; :}
  687. | RelationalExpression:left OP_GT:op ShiftExpression:right
  688. {: RESULT = makeNode("GT"); :}
  689. | RelationalExpression:left OP_LT:op ShiftExpression:right
  690. {: RESULT = makeNode("LT"); :}
  691. | RelationalExpression:left OP_LE:op ShiftExpression:right
  692. {: RESULT = makeNode("LE"); :}
  693. | RelationalExpression:left OP_GE:op ShiftExpression:right
  694. {: RESULT = makeNode("GE"); :}
  695. | RelationalExpression:left INSTANCEOF:op TypeSpecifier:right
  696. {: RESULT = makeNode("INSTANCE"); :}
  697. ;
  698.  
  699. /*
  700. * Extra credit: shift expressions
  701. */
  702. ShiftExpression
  703. ::= AdditiveExpression:rhs
  704. {: RESULT = rhs; :}
  705. ;
  706.  
  707. AdditiveExpression
  708. ::= MultiplicativeExpression:rhs
  709. {: RESULT = rhs; :}
  710. | AdditiveExpression:lhs PLUSOP:op MultiplicativeExpression:rhs
  711. {: RESULT = makeNode("ADDITION: ").adoptChildren(lhs).adoptChildren(rhs);:}
  712. | AdditiveExpression:lhs MINUSOP:op MultiplicativeExpression:rhs
  713. {: RESULT = makeNode("SUBSTRACTION: ").adoptChildren(lhs).adoptChildren(rhs);:}
  714. ;
  715.  
  716. MultiplicativeExpression
  717. ::= CastExpression:rhs
  718. {: RESULT = rhs; :}
  719. | MultiplicativeExpression:lhs ASTERICK:op CastExpression:rhs
  720. {: RESULT = makeNode("MULTIPLICATION: ").adoptChildren(lhs).adoptChildren(rhs); :}
  721. | MultiplicativeExpression:lhs RSLASH:op CastExpression:rhs
  722. {: RESULT = makeNode("DIVISION: ").adoptChildren(lhs).adoptChildren(rhs); :}
  723. | MultiplicativeExpression:lhs PERCENT:op CastExpression:rhs /* remainder */
  724. {: RESULT = makeNode("MODULO: ").adoptChildren(lhs).adoptChildren(rhs); :}
  725. ;
  726.  
  727. /*
  728.  
  729. * Be sure to introduce an explicit cast operator
  730. */
  731. CastExpression
  732. ::= UnaryExpression:rhs /* no cast */
  733. {: RESULT = rhs; :}
  734. | LPAREN PrimitiveType:s RPAREN CastExpression:lue /* More casts coming */
  735. {: RESULT = makeNode(s + " Cast:").adoptChildren(lue); :}
  736. | LPAREN Expression:exp RPAREN LogicalUnaryExpression:lue /* Final cast */
  737. {: RESULT = makeNode("FINAL CAST"); :}
  738. ;
  739.  
  740. /*
  741. * Extra credit: pre-increment and pre-decrement
  742. */
  743. UnaryExpression
  744. ::= LogicalUnaryExpression:rhs
  745. {: RESULT = rhs; :}
  746. | ArithmeticUnaryOperator:op CastExpression:exp
  747. {: RESULT = makeNode("ARITH"); :}
  748. ;
  749.  
  750. ArithmeticUnaryOperator
  751. ::= PLUSOP:rhs
  752. | MINUSOP:rhs
  753. ;
  754.  
  755. LogicalUnaryExpression
  756. ::= PostfixExpression:rhs
  757. {: RESULT = rhs; :}
  758. | LogicalUnaryOperator:op UnaryExpression:uexp
  759. {: RESULT = op.makeSibling(uexp); :}
  760. ;
  761.  
  762. LogicalUnaryOperator
  763. ::= BANG:rhs
  764. | TILDE:rhs
  765. ;
  766.  
  767. Identifier
  768. ::= IDENTIFIER:id
  769. {: RESULT = makeNode(id); :}
  770. ;
  771.  
  772. Literal
  773. ::= LITERAL:lit
  774. {: RESULT = makeNode(lit); :}
  775. ;
  776.  
  777. Number
  778. ::= INTNUMBER:n
  779. {: RESULT = makeNode(n); :}
  780. ;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement