Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* Pair Submission
- Sean Schaffer
- Aaditya Manirajan
- */
- package lab3.autogen;
- import lab3.*;
- import java_cup.runtime.*;
- import java.util.Vector;
- import java.util.Enumeration;
- // $Id: jmm.cup 33 2010-08-09 21:47:19Z cytron $
- /*
- * Java minus minus grammar
- *
- */
- /*
- * This is a standard Java grammar, modified for our use. Many features
- * are noted as "extra credit". You must negotiate
- * the extra credit with the professor.
- *
- * Some features are added too: look for comments to that effect.
- * RC
- */
- action code {:
- /** Code that is included with the action blocks
- *
- */
- /* Need some classes that extend AbstractNode? Here's an example */
- /* The TemporaryNode is just a place holder, and is good for development but
- * should eventually go away.
- */
- class Example extends AbstractNode {
- public String getName() { return "Example"; }
- }
- class TemporaryNode extends AbstractNode {
- private String s;
- public TemporaryNode(String s) {
- this.s = s;
- }
- public String getName() { return s; }
- }
- class IntegerNode extends AbstractNode {
- private Integer val;
- public IntegerNode(Integer val) { this.val = val; }
- public String getName() { return "Integer " + val; }
- }
- /* Factory methods to make nodes
- * Add ones here that make it easy for you.
- The ones given here are temporary placeholders
- */
- public AbstractNode makeNode(Symbol s) { return new TemporaryNode(symString.symToString[s.sym]); }
- public AbstractNode makeNode(String s) { return new TemporaryNode(s); }
- public AbstractNode makeNode(Integer i) { return new IntegerNode(i); }
- :};
- /*
- * Almost all of these can just be Symbol types, used for parsing. Occasionally,
- * a terminal has semantic information of use, as was the case for number in hw2.
- * In those cases, declare the Symbol appropriately but you'll have to modify the
- * Scanner to return the right type. I've done this for integer and string types below
- */
- terminal Symbol OP_GE, OP_LE, OP_EQ, OP_NE, OP_GT, OP_LT;
- terminal Symbol OP_LAND, OP_LOR;
- terminal Symbol INSTANCEOF;
- terminal Symbol HAT, TILDE;
- terminal Symbol BOOLEAN;
- terminal Symbol CLASS;
- terminal Symbol ELSE;
- terminal Symbol IF, INT;
- terminal Symbol NEW, NULL;
- terminal Symbol PRIVATE, PUBLIC;
- terminal Symbol RETURN;
- terminal Symbol STATIC, SUPER;
- terminal Symbol THIS;
- terminal Symbol VOID;
- terminal Symbol WHILE;
- terminal Symbol ASS_ADD;
- terminal Symbol LPAREN, RPAREN, LBRACE, RBRACE, EQUALS;
- terminal Symbol PERIOD, COLON, SEMICOLON, COMMA, PIPE, AND, ASTERICK;
- terminal Symbol PLUSOP, MINUSOP, RSLASH, PERCENT, QUESTION;
- terminal Symbol BANG;
- terminal String IDENTIFIER, LITERAL;
- terminal Integer INTNUMBER;
- /* To save you typing, I've made all these AbstracNode types. You will want
- * to customize them as you go.
- */
- non terminal AbstractNode CompilationUnit;
- non terminal AbstractNode FieldVariableDeclaration;
- non terminal AbstractNode MethodDeclaration;
- non terminal AbstractNode MethodDeclarator;
- non terminal AbstractNode ParameterList, Parameter;
- non terminal AbstractNode MethodBody, ConstructorDeclaration;
- non terminal AbstractNode StaticInitializer;
- non terminal AbstractNode Block;
- non terminal AbstractNode LocalVariableDeclarationsAndStatements;
- non terminal AbstractNode LocalVariableDeclarationOrStatement;
- non terminal AbstractNode LocalVariableDeclarationStatement ;
- non terminal AbstractNode Statement, EmptyStatement;
- non terminal AbstractNode MatchedStatement, UnMatchedStatement;
- non terminal AbstractNode ExpressionStatement;
- non terminal AbstractNode MatchedSelectionStatement, UnMatchedSelectionStatement;
- non terminal AbstractNode MatchedIterationStatement, UnMatchedIterationStatement;
- non terminal AbstractNode PrimaryExpression;
- non terminal AbstractNode NotJustName, ComplexPrimary, ComplexPrimaryNoParenthesis;
- non terminal AbstractNode FieldAccess, MethodCall, MethodReference;
- non terminal AbstractNode SpecialName, ArgumentList, AllocationExpression;
- non terminal AbstractNode PostfixExpression;
- non terminal AbstractNode UnaryExpression, LogicalUnaryExpression;
- non terminal AbstractNode LogicalUnaryOperator, ArithmeticUnaryOperator;
- non terminal AbstractNode CastExpression, MultiplicativeExpression;
- non terminal AbstractNode AdditiveExpression, ShiftExpression, RelationalExpression;
- non terminal AbstractNode EqualityExpression, AndExpression, ExclusiveOrExpression;
- non terminal AbstractNode InclusiveOrExpression, ConditionalAndExpression;
- non terminal AbstractNode ConditionalOrExpression;
- non terminal AbstractNode ConditionalExpression, AssignmentExpression;
- non terminal AbstractNode AssignmentOperator;
- non terminal AbstractNode Expression;
- non terminal AbstractNode ReturnStatement;
- non terminal AbstractNode Identifier;
- non terminal AbstractNode Literal;
- non terminal AbstractNode Number;
- non terminal AbstractNode DeclaratorName;
- non terminal AbstractNode FieldVariableDeclaratorName;
- non terminal AbstractNode MethodDeclaratorName;
- non terminal AbstractNode LocalVariableDeclaratorName;
- non terminal AbstractNode TypeDeclarations;
- non terminal AbstractNode TypeDeclaration;
- non terminal AbstractNode ClassDeclaration;
- non terminal AbstractNode ClassBody;
- non terminal AbstractNode Modifiers;
- non terminal AbstractNode FieldDeclarations;
- non terminal AbstractNode FieldDeclaration;
- non terminal AbstractNode FieldVariableDeclarators;
- non terminal AbstractNode LocalVariableDeclarators;
- non terminal AbstractNode QualifiedName;
- non terminal AbstractNode TypeName, TypeSpecifier;
- non terminal AbstractNode PrimitiveType;
- start with CompilationUnit;
- CompilationUnit
- ::= TypeDeclarations:td
- {:
- AbstractNode prog = makeNode("Program").adoptChildren(td);
- System.out.println("\n\n");
- prog.walkTree(new PrintTree(System.out));
- :}
- ;
- /*
- * Simple node magic to link nodes together as siblings. Covered
- * in class -- you have to be aware of how the list is growing
- * These children will be adopted by CompilationUnit rule above.
- */
- TypeDeclarations
- ::= TypeDeclaration:td
- {: RESULT = td; :}
- | TypeDeclarations:tds TypeDeclaration:td
- {: RESULT = tds.makeSibling(td); :}
- ;
- /*
- * Extra credit: interfaces, but classes are all we'll deal with by default
- */
- TypeDeclaration
- ::= ClassDeclaration:rhs
- {:
- RESULT = rhs;
- :}
- ;
- ClassDeclaration
- ::= Modifiers:mods CLASS:cl Identifier:id ClassBody:clb
- {:
- RESULT = makeNode(String.format("DECLARATION OF %s Class %s",mods ,id)).adoptChildren(clb);
- :}
- ;
- /*
- * Process bottom-up to figure out whether the Modifier
- * is static or not
- * is public or not
- * A pair of booleans, like IntPair could be used, or IntPair could be used
- * if you know what I mean.
- */
- Modifiers
- ::= PUBLIC
- {: RESULT = makeNode("Public"); :}
- | PRIVATE
- {: RESULT = makeNode("Private"); :}
- | STATIC
- {: RESULT = makeNode("Static"); :}
- | Modifiers:mds PUBLIC
- {: RESULT = makeNode("Public " + mds); :}
- | Modifiers:mds PRIVATE
- {: RESULT = makeNode("Private " + mds); :}
- | Modifiers:mds STATIC
- {: RESULT = makeNode("Static" + mds); :}
- ;
- /*
- * Extra credit: other types
- */
- PrimitiveType
- ::= BOOLEAN:tok
- {: RESULT = makeNode(tok); :}
- | INT:tok
- {: RESULT = makeNode(tok); :}
- | VOID:tok
- {: RESULT = makeNode(tok); :}
- ;
- /*
- * You need a nice structure to represent this list of identifiers.
- * You might consider java.util.Vector
- */
- QualifiedName
- ::= Identifier:id
- {: RESULT = id;:}
- | QualifiedName:qn PERIOD Identifier:id
- {: RESULT = makeNode(String.format("%s/%s",qn.getName(), id.getName())); :}
- ;
- /*
- * In a given program, FieldDeclarations can occur in any order.
- * But we would like them grouped together.
- * So, structure your AST so that the items coming back from
- * FieldDeclarations are grouped by:
- *
- * fields, statics, constructors, methods, inner classes
- *
- * (run the class solution if confused)
- */
- ClassBody
- ::= LBRACE FieldDeclarations:fds RBRACE
- {:
- RESULT = makeNode("BODY:").adoptChildren(fds);
- :}
- | LBRACE RBRACE
- ;
- FieldDeclarations
- ::= FieldDeclaration:fd
- {: RESULT = fd; :}
- | FieldDeclarations:fds FieldDeclaration:fd
- {: RESULT = fds.makeSibling(fd); :}
- ;
- FieldDeclaration
- ::= FieldVariableDeclaration:fvd SEMICOLON
- {: RESULT = makeNode("FIELD: ").adoptChildren(fvd); :}
- | MethodDeclaration:rhs'
- {: RESULT = makeNode("METHOD: ").adoptChildren(rhs); :}
- | ConstructorDeclaration:rhs
- {: RESULT = makeNode("CONSTRUCTOR: ").adoptChildren(rhs); :}
- | StaticInitializer:rhs
- {: RESULT = makeNode("STATIC: ").adoptChildren(rhs); :}
- | ClassDeclaration
- {: RESULT = makeNode("INNER CLASS: "); :}
- ;
- /*
- * This isn't structured so nicely for a bottom up parse. Recall
- * the example I did in class for Digits, where the "type" of the digits
- * (i.e., the base) is sitting off to the side. You'll have to do something
- * here to get the information where you want it, so that the declarations can
- * be suitably annotated with their type and modifier information.
- */
- FieldVariableDeclaration
- ::= Modifiers:m TypeSpecifier:t FieldVariableDeclarators:fvds
- {: RESULT = makeNode(String.format("%s %s", m, t)).adoptChildren(fvds); :}
- ;
- TypeSpecifier
- ::= TypeName:rhs
- {: RESULT = rhs; :}
- ;
- TypeName
- ::= PrimitiveType:rhs
- {: RESULT = rhs; :}
- | QualifiedName:rhs
- {: RESULT = rhs; :}
- ;
- FieldVariableDeclarators
- ::= FieldVariableDeclaratorName:v
- {: RESULT = v; :}
- | FieldVariableDeclarators:fds COMMA FieldVariableDeclaratorName:v
- {: RESULT = fds.makeSibling(v); :}
- ;
- /*
- * We require modifiers, extra credit for package stuff
- */
- MethodDeclaration
- ::= Modifiers:m TypeSpecifier:t MethodDeclarator:md MethodBody:rhs
- {:
- AbstractNode method = makeNode(String.format("%s %s %s",m ,t, md.getName()));
- AbstractNode params = makeNode("PARAMS: ").adoptChildren(md);
- method.adoptChildren(params);
- method.adoptChildren(rhs);
- RESULT = method;
- :}
- ;
- MethodDeclarator
- ::= MethodDeclaratorName:dn LPAREN ParameterList:pl RPAREN
- {: RESULT = dn.adoptChildren(pl); :}
- | MethodDeclaratorName:dn LPAREN RPAREN
- {: RESULT = dn; :}
- ;
- ParameterList
- ::= Parameter:rhs
- {: RESULT = rhs; :}
- | ParameterList:spine COMMA Parameter:rhs
- {: RESULT = spine.makeSibling(rhs); :}
- ;
- Parameter
- ::= TypeSpecifier:t DeclaratorName:dn
- {: RESULT = makeNode(String.format("PARAM: %s %s",t ,dn)); :}
- ;
- DeclaratorName
- ::= Identifier:in
- {: RESULT = in; :}
- ;
- MethodDeclaratorName
- ::= Identifier:in
- {: RESULT = in; :}
- ;
- FieldVariableDeclaratorName
- ::= Identifier:in
- {: RESULT = in; :}
- ;
- LocalVariableDeclaratorName
- ::= Identifier:in
- {: RESULT = in; :}
- ;
- MethodBody
- ::= Block:rhs
- {: RESULT = rhs; :}
- ;
- ConstructorDeclaration
- ::= Modifiers:m MethodDeclarator:md Block:rhs
- {: AbstractNode type = m;
- AbstractNode paramBlock = md.adoptChildren(rhs);
- RESULT = type.adoptChildren(paramBlock);
- :}
- ;
- StaticInitializer
- ::= STATIC Block:rhs
- {: RESULT = rhs; :}
- ;
- /*
- * These can't be reorganized, because the order matters.
- * For example: int i; i = 5; int j = i;
- */
- Block
- ::= LBRACE LocalVariableDeclarationsAndStatements:stmts RBRACE
- {: RESULT = makeNode("BLOCK: ").adoptChildren(stmts); :}
- | LBRACE RBRACE
- ;
- LocalVariableDeclarationsAndStatements
- ::= LocalVariableDeclarationOrStatement:rhs
- {: RESULT = rhs; :}
- | LocalVariableDeclarationsAndStatements:lvds
- LocalVariableDeclarationOrStatement:rhs
- {: RESULT = lvds.makeSibling(rhs); :}
- ;
- LocalVariableDeclarationOrStatement
- ::= LocalVariableDeclarationStatement:rhs
- {: RESULT = rhs; :}
- | Statement:rhs
- {: RESULT = rhs; :}
- ;
- LocalVariableDeclarationStatement
- ::= TypeSpecifier:t LocalVariableDeclarators:rhs SEMICOLON
- {: RESULT = makeNode(String.format("LOCAL %s:",t)).adoptChildren(rhs); :}
- | ClassDeclaration /* Inner classes */
- ;
- LocalVariableDeclarators
- ::= LocalVariableDeclaratorName:v
- {: RESULT = v; :}
- | LocalVariableDeclarators:fds COMMA LocalVariableDeclaratorName:v
- {: RESULT = fds.makeSibling(v); :}
- ;
- Statement
- ::= MatchedStatement:ms
- {: RESULT = ms; :}
- | UnMatchedStatement:us
- {: RESULT = us; :}
- ;
- UnMatchedStatement
- ::= UnMatchedSelectionStatement:uss
- {: RESULT = uss; :}
- | UnMatchedIterationStatement:uis
- {: RESULT = uis; :}
- ;
- MatchedStatement
- ::= EmptyStatement:es
- {: RESULT = es; :}
- | ExpressionStatement:rhs SEMICOLON
- {: RESULT = rhs; :}
- | MatchedSelectionStatement:mss
- {: RESULT = makeNode("IF: ").adoptChildren(mss); :}
- | MatchedIterationStatement:mis
- {: RESULT = makeNode("WHILE: ").adoptChildren(mis); :}
- | ReturnStatement:rs
- {: RESULT = makeNode("RETURN: ").adoptChildren(rs); :}
- | Block:rhs
- {: RESULT = rhs; :}
- ;
- EmptyStatement
- ::= SEMICOLON
- {: RESULT = makeNode("Empty Statement"); :}
- ;
- ExpressionStatement
- ::= Expression:rhs
- {:RESULT = rhs; :}
- ;
- /*
- * You will eventually have to address the shift/reduce error that
- * occurs when the second IF-rule is uncommented.
- *
- */
- MatchedSelectionStatement
- ::= IF LPAREN Expression:exp RPAREN MatchedStatement:ms ELSE MatchedStatement:rhs
- {:
- AbstractNode cond = makeNode("CONDITION: ").adoptChildren(exp);
- AbstractNode block = makeNode("BLOCK: ").adoptChildren(ms);
- AbstractNode other = makeNode("ELSE: ").adoptChildren(rhs);
- RESULT = cond.makeSibling(block).makeSibling(other);
- :}
- ;
- UnMatchedSelectionStatement
- ::= IF LPAREN Expression:exp RPAREN MatchedStatement:ms ELSE UnMatchedStatement:rhs
- {:
- AbstractNode cond = makeNode("CONDITION: ").adoptChildren(exp);
- AbstractNode block = makeNode("BLOCK: ").adoptChildren(ms);
- AbstractNode other = makeNode("ELSE: ").adoptChildren(rhs);
- RESULT = cond.makeSibling(block).makeSibling(other);
- :}
- | IF LPAREN Expression:exp RPAREN Statement:stmt
- {:
- AbstractNode cond = makeNode("CONDITION: ").adoptChildren(exp);
- AbstractNode block = makeNode("BLOCK: ").adoptChildren(stmt);
- RESULT = cond.makeSibling(block);
- :}
- ;
- /*
- * Extra Credit: FOR statement, DO statement
- */
- MatchedIterationStatement
- ::= WHILE LPAREN Expression:exp RPAREN MatchedStatement:rhs
- {:
- AbstractNode cond = makeNode("CONDITION: ").adoptChildren(exp);
- AbstractNode block = makeNode("BLOCK: ").adoptChildren(rhs);
- RESULT = cond.makeSibling(block);
- :}
- ;
- UnMatchedIterationStatement
- ::= WHILE LPAREN Expression:exp RPAREN UnMatchedStatement:rhs
- {:
- AbstractNode cond = makeNode("CONDITION: ").adoptChildren(exp);
- AbstractNode block = makeNode("BLOCK: ").adoptChildren(rhs);
- RESULT = cond.makeSibling(block);
- :}
- ;
- ReturnStatement
- ::= RETURN Expression:exp SEMICOLON
- {: RESULT = exp; :}
- | RETURN SEMICOLON
- ;
- PrimaryExpression
- ::= QualifiedName:t
- {: RESULT = t; :}
- | NotJustName:rhs
- {: RESULT = rhs; :}
- /*
- * You will eventually have to explain the conflicts that arise when the rule below
- * is uncommented.
- * This rule lets a block ( { .... } ) serve anywhere a primary expression could.
- * So you could write a = { while (h>5) h = h -k; };
- *
- * | Block:rhs
- */
- ;
- NotJustName
- ::= SpecialName:sn
- {: RESULT = sn; :}
- | AllocationExpression:ae
- {: RESULT = makeNode("ALLOCATION: ").adoptChildren(ae); :}
- | ComplexPrimary:rhs
- {: RESULT = rhs; :}
- ;
- ComplexPrimary
- ::= LPAREN Expression:rhs RPAREN
- {: RESULT = rhs; :}
- | ComplexPrimaryNoParenthesis:rhs
- {: RESULT = rhs; :}
- ;
- ComplexPrimaryNoParenthesis
- ::= Literal:rhs
- {: RESULT = rhs; :}
- | Number:rhs
- {: RESULT = rhs; :}
- | FieldAccess:fa
- {: RESULT = fa; :}
- | MethodCall:mc
- {: RESULT = mc; :}
- ;
- FieldAccess
- ::= NotJustName:njn PERIOD Identifier:id
- {: RESULT = makeNode("ACCESS: ").adoptChildren(njn).adoptChildren(id); :}
- ;
- MethodCall
- ::= MethodReference:lhs LPAREN ArgumentList:rhs RPAREN
- {: RESULT = makeNode("CALL: ").adoptChildren(lhs).adoptChildren(rhs); :}
- | MethodReference:lhs LPAREN RPAREN
- {: RESULT = makeNode("CALL: ").adoptChildren(lhs); :}
- ;
- MethodReference
- ::= ComplexPrimaryNoParenthesis:rhs
- {: RESULT = makeNode("METHOD: ").adoptChildren(rhs); :}
- | QualifiedName:rhs
- {: RESULT = makeNode("METHOD: ").adoptChildren(rhs); :}
- | SpecialName:rhs
- {: RESULT = makeNode("METHOD: ").adoptChildren(rhs); :}
- ;
- SpecialName
- ::= THIS
- {: RESULT = makeNode("THIS"); :}
- | NULL
- {: RESULT = makeNode("NULL"); :}
- | SUPER
- {: RESULT = makeNode("SUPER"); :}
- ;
- ArgumentList
- ::= Expression:exp
- {: RESULT = makeNode("ARGUMENTS: ").adoptChildren(exp); :}
- | ArgumentList:lhs COMMA Expression:exp
- {: RESULT = lhs.makeSibling(exp); :}
- ;
- /*
- * Extra credit: anonymous subclasses
- */
- AllocationExpression
- ::= NEW TypeName:t LPAREN ArgumentList:al RPAREN
- {: RESULT = t.adoptChildren(al); :}
- | NEW TypeName:t LPAREN RPAREN
- {: RESULT = t; :}
- ;
- /*
- * Extra credit, add post increment and decrement
- */
- PostfixExpression
- ::= PrimaryExpression:rhs
- {: RESULT = rhs; :}
- ;
- Expression
- ::= AssignmentExpression:rhs
- {: RESULT = rhs; :}
- ;
- /*
- * Here we go. Following are a bunch of rules to handle the right priority and
- * associativity of operators. These rules can be treated fairly uniformly
- * for now
- * However, be aware that down the road, you will want subclassees that
- * can distinguish
- * the nodes by type, so that you can generate different code for
- * plus vs. minus, for example.
- */
- /*
- * What kind of associativity do we get for assignment expressions - why?
- */
- AssignmentExpression
- ::= ConditionalExpression:rhs
- {: RESULT = rhs; :}
- | UnaryExpression:lhs AssignmentOperator:op AssignmentExpression:rhs
- {: RESULT = makeNode(op + ": ").adoptChildren(lhs).adoptChildren(rhs); :}
- ;
- AssignmentOperator
- ::= EQUALS:tok
- {: RESULT = makeNode("ASSIGNMENT"); :}
- | ASS_ADD:tok /* There are more of these if you're interested */
- {: RESULT = makeNode("ASSIGNMENT ADD"); :}
- ;
- ConditionalExpression
- ::= ConditionalOrExpression:coe
- {: RESULT = coe; :}
- | ConditionalOrExpression:coe QUESTION Expression:exp COLON ConditionalExpression:rhs
- {: RESULT = makeNode("TERNARY:").adoptChildren(coe).adoptChildren(exp).adoptChildren(rhs); :}
- ;
- ConditionalOrExpression
- ::= ConditionalAndExpression:cae
- {: RESULT = cae; :}
- | ConditionalOrExpression:left OP_LOR:op ConditionalAndExpression:right /* short-circuit OR */
- {: RESULT = makeNode("LOR:").adoptChildren(left).adoptChildren(right); :}
- ;
- ConditionalAndExpression
- ::= InclusiveOrExpression:rhs
- {: RESULT = rhs; :}
- | ConditionalAndExpression:left OP_LAND:op InclusiveOrExpression:right /* short-circuit AND */
- {: RESULT = makeNode("LAND:").adoptChildren(left).adoptChildren(right); :}
- ;
- InclusiveOrExpression
- ::= ExclusiveOrExpression:rhs
- {: RESULT = rhs; :}
- | InclusiveOrExpression:left PIPE:op ExclusiveOrExpression:right
- {: RESULT = makeNode("OR:").adoptChildren(left).adoptChildren(right); :}
- ;
- ExclusiveOrExpression
- ::= AndExpression:rhs
- {: RESULT = rhs; :}
- | ExclusiveOrExpression:left HAT:op AndExpression:right
- {: RESULT = makeNode("XOR:").adoptChildren(left).adoptChildren(right); :}
- ;
- AndExpression
- ::= EqualityExpression:rhs
- {: RESULT = rhs; :}
- | AndExpression:left AND:op EqualityExpression:right
- {: RESULT = makeNode("AND:").adoptChildren(left).adoptChildren(right); :}
- ;
- EqualityExpression
- ::= RelationalExpression:rhs
- {: RESULT = rhs; :}
- | EqualityExpression:left OP_EQ:op RelationalExpression:right
- {: RESULT = makeNode("EQUAL TO:").adoptChildren(left).adoptChildren(right); :}
- | EqualityExpression:left OP_NE:op RelationalExpression:right
- {: RESULT = makeNode("NOT EQUAL TO:").adoptChildren(left).adoptChildren(right); :}
- ;
- RelationalExpression
- ::= ShiftExpression:rhs
- {: RESULT = rhs; :}
- | RelationalExpression:left OP_GT:op ShiftExpression:right
- {: RESULT = makeNode("GREATER THAN:").adoptChildren(left).adoptChildren(right); :}
- | RelationalExpression:left OP_LT:op ShiftExpression:right
- {: RESULT = makeNode("LESS THAN:").adoptChildren(left).adoptChildren(right); :}
- | RelationalExpression:left OP_LE:op ShiftExpression:right
- {: RESULT = makeNode("LESS THAN OR EQUAL:").adoptChildren(left).adoptChildren(right); :}
- | RelationalExpression:left OP_GE:op ShiftExpression:right
- {: RESULT = makeNode("GREATER THAN OR EQUAL:").adoptChildren(left).adoptChildren(right); :}
- | RelationalExpression:left INSTANCEOF:op TypeSpecifier:right
- {: RESULT = makeNode("INSTANCE OF:").adoptChildren(left).adoptChildren(right); :}
- ;
- /*
- * Extra credit: shift expressions
- */
- ShiftExpression
- ::= AdditiveExpression:rhs
- {: RESULT = rhs; :}
- ;
- AdditiveExpression
- ::= MultiplicativeExpression:rhs
- {: RESULT = rhs; :}
- | AdditiveExpression:lhs PLUSOP:op MultiplicativeExpression:rhs
- {: RESULT = makeNode("ADDITION: ").adoptChildren(lhs).adoptChildren(rhs);:}
- | AdditiveExpression:lhs MINUSOP:op MultiplicativeExpression:rhs
- {: RESULT = makeNode("SUBSTRACTION: ").adoptChildren(lhs).adoptChildren(rhs);:}
- ;
- MultiplicativeExpression
- ::= CastExpression:rhs
- {: RESULT = rhs; :}
- | MultiplicativeExpression:lhs ASTERICK:op CastExpression:rhs
- {: RESULT = makeNode("MULTIPLICATION: ").adoptChildren(lhs).adoptChildren(rhs); :}
- | MultiplicativeExpression:lhs RSLASH:op CastExpression:rhs
- {: RESULT = makeNode("DIVISION: ").adoptChildren(lhs).adoptChildren(rhs); :}
- | MultiplicativeExpression:lhs PERCENT:op CastExpression:rhs /* remainder */
- {: RESULT = makeNode("MODULO: ").adoptChildren(lhs).adoptChildren(rhs); :}
- ;
- /*
- * Be sure to introduce an explicit cast operator
- */
- CastExpression
- ::= UnaryExpression:rhs /* no cast */
- {: RESULT = rhs; :}
- | LPAREN PrimitiveType:s RPAREN CastExpression:lue /* More casts coming */
- {: RESULT = makeNode(String.format("CAST %s:",s)).adoptChildren(lue); :}
- | LPAREN Expression:exp RPAREN LogicalUnaryExpression:lue /* Final cast */
- {: RESULT = lue.adoptChildren(exp); :}
- ;
- /*
- * Extra credit: pre-increment and pre-decrement
- */
- UnaryExpression
- ::= LogicalUnaryExpression:rhs
- {: RESULT = rhs; :}
- | ArithmeticUnaryOperator:op CastExpression:exp
- {: RESULT = makeNode("ARITH"); :}
- ;
- ArithmeticUnaryOperator
- ::= PLUSOP:pl
- {: RESULT = makeNode(pl); :}
- | MINUSOP:ms
- {: RESULT = makeNode(ms); :}
- ;
- LogicalUnaryExpression
- ::= PostfixExpression:rhs
- {: RESULT = rhs; :}
- | LogicalUnaryOperator:op UnaryExpression:uexp
- {: RESULT = makeNode(op + ":").adoptChildren(uexp); :}
- ;
- LogicalUnaryOperator
- ::= BANG:bg
- {: RESULT = makeNode(bg); :}
- | TILDE:td
- {: RESULT = makeNode(td); :}
- ;
- Identifier
- ::= IDENTIFIER:id
- {: RESULT = makeNode(id); :}
- ;
- Literal
- ::= LITERAL:lit
- {: RESULT = makeNode(lit); :}
- ;
- Number
- ::= INTNUMBER:n
- {: RESULT = makeNode(n); :}
- ;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement