/* * Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ options { JAVA_UNICODE_ESCAPE = true; STATIC = false;} PARSER_BEGIN(ExpressionParser) package com.sun.tools.example.debug.expr; import com.sun.jdi.*;import java.util.Stack;import java.util.List;import java.util.ArrayList; public class ExpressionParser { Stack stack = new Stack(); VirtualMachine vm = null; GetFrame frameGetter = null; private static GetFrame lastFrameGetter; private static LValue lastLValue; LValue peek() { return (LValue)stack.peek(); } LValue pop() { return (LValue)stack.pop(); } void push(LValue lval) { stack.push(lval); } public static Value getMassagedValue() throws ParseException { return lastLValue.getMassagedValue(lastFrameGetter); } public interface GetFrame { StackFrame get() throws IncompatibleThreadStateException; } public static Value evaluate(String expr, VirtualMachine vm, GetFrame frameGetter) throws ParseException, InvocationException, InvalidTypeException, ClassNotLoadedException, IncompatibleThreadStateException { // TODO StringBufferInputStream is deprecated. java.io.InputStream in = new java.io.StringBufferInputStream(expr); ExpressionParser parser = new ExpressionParser(in); parser.vm = vm; parser.frameGetter = frameGetter; Value value = null; parser.Expression(); lastFrameGetter = frameGetter; lastLValue = parser.pop(); return lastLValue.getValue(); } public static void main(String args[]) { ExpressionParser parser; System.out.print("Java Expression Parser: "); if (args.length == 0) { System.out.println("Reading from standard input . . ."); parser = new ExpressionParser(System.in); } else if (args.length == 1) { System.out.println("Reading from file " + args[0] + " . . ."); try { parser = new ExpressionParser(new java.io.FileInputStream(args[0])); } catch (java.io.FileNotFoundException e) { System.out.println("Java Parser Version 1.0.2: File " + args[0] + " not found."); return; } } else { System.out.println("Usage is one of:"); System.out.println(" java ExpressionParser < inputfile"); System.out.println("OR"); System.out.println(" java ExpressionParser inputfile"); return; } try { parser.Expression(); System.out.print("Java Expression Parser: "); System.out.println("Java program parsed successfully."); } catch (ParseException e) { System.out.print("Java Expression Parser: "); System.out.println("Encountered errors during parse."); } } } PARSER_END(ExpressionParser) SKIP : /* WHITE SPACE */{ " "| "\t"| "\n"| "\r"| "\f"} SPECIAL_TOKEN : /* COMMENTS */{ <SINGLE_LINE_COMMENT: "//" (~["\n","\r"])* ("\n"|"\r"|"\r\n")>| <FORMAL_COMMENT: "/**" (~["*"])* "*" ("*" | (~["*","/"] (~["*"])* "*"))* "/">| <MULTI_LINE_COMMENT: "/*" (~["*"])* "*" ("*" | (~["*","/"] (~["*"])* "*"))* "/">} TOKEN : /* RESERVED WORDS AND LITERALS */{ < ABSTRACT: "abstract" >| < BOOLEAN: "boolean" >| < BREAK: "break" >| < BYTE: "byte" >| < CASE: "case" >| < CATCH: "catch" >| < CHAR: "char" >| < CLASS: "class" >| < CONST: "const" >| < CONTINUE: "continue" >| < _DEFAULT: "default" >| < DO: "do" >| < DOUBLE: "double" >| < ELSE: "else" >| < EXTENDS: "extends" >| < FALSE: "false" >| < FINAL: "final" >| < FINALLY: "finally" >| < FLOAT: "float" >| < FOR: "for" >| < GOTO: "goto" >| < IF: "if" >| < IMPLEMENTS: "implements" >| < IMPORT: "import" >| < INSTANCEOF: "instanceof" >| < INT: "int" >| < INTERFACE: "interface" >| < LONG: "long" >| < NATIVE: "native" >| < NEW: "new" >| < NULL: "null" >| < PACKAGE: "package">| < PRIVATE: "private" >| < PROTECTED: "protected" >| < PUBLIC: "public" >| < RETURN: "return" >| < SHORT: "short" >| < STATIC: "static" >| < SUPER: "super" >| < SWITCH: "switch" >| < SYNCHRONIZED: "synchronized" >| < THIS: "this" >| < THROW: "throw" >| < THROWS: "throws" >| < TRANSIENT: "transient" >| < TRUE: "true" >| < TRY: "try" >| < VOID: "void" >| < VOLATILE: "volatile" >| < WHILE: "while" >} TOKEN : /* LITERALS */{ < INTEGER_LITERAL: <DECIMAL_LITERAL> (["l","L"])? | <HEX_LITERAL> (["l","L"])? | <OCTAL_LITERAL> (["l","L"])? >| < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >| < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >| < #OCTAL_LITERAL: "0" (["0"-"7"])* >| < FLOATING_POINT_LITERAL: (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? (["f","F","d","D"])? | "." (["0"-"9"])+ (<EXPONENT>)? (["f","F","d","D"])? | (["0"-"9"])+ <EXPONENT> (["f","F","d","D"])? | (["0"-"9"])+ (<EXPONENT>)? ["f","F","d","D"] >| < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >| < CHARACTER_LITERAL: "'" ( (~["'","\\","\n","\r"]) | ("\\" ( ["n","t","b","r","f","\\","'","\""] | ["0"-"7"] ( ["0"-"7"] )? | ["0"-"3"] ["0"-"7"] ["0"-"7"] ) ) ) "'" >| < STRING_LITERAL: "\"" ( (~["\"","\\","\n","\r"]) | ("\\" ( ["n","t","b","r","f","\\","'","\""] | ["0"-"7"] ( ["0"-"7"] )? | ["0"-"3"] ["0"-"7"] ["0"-"7"] ) ) )* "\"" >} TOKEN : /* IDENTIFIERS */{ < IDENTIFIER: <LETTER> (<LETTER>|<DIGIT>)* >| < #LETTER: [ "\u0024", "\u0041"-"\u005a", "\u005f", "\u0061"-"\u007a", "\u00c0"-"\u00d6", "\u00d8"-"\u00f6", "\u00f8"-"\u00ff", "\u0100"-"\u1fff", "\u3040"-"\u318f", "\u3300"-"\u337f", "\u3400"-"\u3d2d", "\u4e00"-"\u9fff", "\uf900"-"\ufaff" ] >| < #DIGIT: [ "\u0030"-"\u0039", "\u0660"-"\u0669", "\u06f0"-"\u06f9", "\u0966"-"\u096f", "\u09e6"-"\u09ef", "\u0a66"-"\u0a6f", "\u0ae6"-"\u0aef", "\u0b66"-"\u0b6f", "\u0be7"-"\u0bef", "\u0c66"-"\u0c6f", "\u0ce6"-"\u0cef", "\u0d66"-"\u0d6f", "\u0e50"-"\u0e59", "\u0ed0"-"\u0ed9", "\u1040"-"\u1049" ] >} TOKEN : /* SEPARATORS */{ < LPAREN: "(" >| < RPAREN: ")" >| < LBRACE: "{" >| < RBRACE: "}" >| < LBRACKET: "[" >| < RBRACKET: "]" >| < SEMICOLON: ";" >| < COMMA: "," >| < DOT: "." >} TOKEN : /* OPERATORS */{ < ASSIGN: "=" >| < GT: ">" >| < LT: "<" >| < BANG: "!" >| < TILDE: "~" >| < HOOK: "?" >| < COLON: ":" >| < EQ: "==" >| < LE: "<=" >| < GE: ">=" >| < NE: "!=" >| < SC_OR: "||" >| < SC_AND: "&&" >| < INCR: "++" >| < DECR: "--" >| < PLUS: "+" >| < MINUS: "-" >| < STAR: "*" >| < SLASH: "/" >| < BIT_AND: "&" >| < BIT_OR: "|" >| < XOR: "^" >| < REM: "%" >| < LSHIFT: "<<" >| < RSIGNEDSHIFT: ">>" >| < RUNSIGNEDSHIFT: ">>>" >| < PLUSASSIGN: "+=" >| < MINUSASSIGN: "-=" >| < STARASSIGN: "*=" >| < SLASHASSIGN: "/=" >| < ANDASSIGN: "&=" >| < ORASSIGN: "|=" >| < XORASSIGN: "^=" >| < REMASSIGN: "%=" >| < LSHIFTASSIGN: "<<=" >| < RSIGNEDSHIFTASSIGN: ">>=" >| < RUNSIGNEDSHIFTASSIGN: ">>>=" >} /***************************************** * THE JAVA LANGUAGE GRAMMAR STARTS HERE * *****************************************/ /* * Type, name and expression syntax follows. */ void Type() :{}{ ( PrimitiveType() | Name() ) ( "[" "]" )*} void PrimitiveType() :{}{ "boolean"| "char"| "byte"| "short"| "int"| "long"| "float"| "double"} String Name() :{StringBuffer sb = new StringBuffer();}{ <IDENTIFIER> { sb.append(token); } ( LOOKAHEAD(2) "." <IDENTIFIER> { sb.append('.'); sb.append(token); } )* { return sb.toString(); }} void NameList() :{}{ Name() ( "," Name() )*} /* * Expression syntax follows. */ void Expression() :{}{ LOOKAHEAD( PrimaryExpression() AssignmentOperator() ) Assignment()| ConditionalExpression()} void Assignment() :{}{ PrimaryExpression() AssignmentOperator() Expression() { LValue exprVal = pop(); pop().setValue(exprVal); push(exprVal);}} void AssignmentOperator() :{}{ "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | ">>>=" | "&=" | "^=" | "|="} void ConditionalExpression() :{}{ ConditionalOrExpression() [ "?" Expression() ":" ConditionalExpression() { LValue falseBranch = pop(); LValue trueBranch = pop(); Value cond = pop().interiorGetValue(); if (cond instanceof BooleanValue) { push(((BooleanValue)cond).booleanValue()? trueBranch : falseBranch); } else { throw new ParseException("Condition must be boolean"); } } ]} void ConditionalOrExpression() :{}{ ConditionalAndExpression() ( "||" ConditionalAndExpression() { throw new ParseException("operation not yet supported"); } )*} void ConditionalAndExpression() :{}{ InclusiveOrExpression() ( "&&" InclusiveOrExpression() { throw new ParseException("operation not yet supported"); } )*} void InclusiveOrExpression() :{}{ ExclusiveOrExpression() ( "|" ExclusiveOrExpression() { throw new ParseException("operation not yet supported"); } )*} void ExclusiveOrExpression() :{}{ AndExpression() ( "^" AndExpression() { throw new ParseException("operation not yet supported"); } )*} void AndExpression() :{}{ EqualityExpression() ( "&" EqualityExpression() { throw new ParseException("operation not yet supported"); } )*} void EqualityExpression() :{Token tok;}{ InstanceOfExpression() ( ( tok = "==" | tok = "!=" ) InstanceOfExpression() { LValue left = pop(); push( LValue.booleanOperation(vm, tok, pop(), left) ); } )*} void InstanceOfExpression() :{}{ RelationalExpression() [ "instanceof" Type() { throw new ParseException("operation not yet supported"); } ]}Lines 1–500 of 724. Load more
/* * Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ options { JAVA_UNICODE_ESCAPE = true; STATIC = false; } PARSER_BEGIN(ExpressionParser) package com.sun.tools.example.debug.expr; import com.sun.jdi.*; import java.util.Stack; import java.util.List; import java.util.ArrayList; public class ExpressionParser { Stack stack = new Stack(); VirtualMachine vm = null; GetFrame frameGetter = null; private static GetFrame lastFrameGetter; private static LValue lastLValue; LValue peek() { return (LValue)stack.peek(); } LValue pop() { return (LValue)stack.pop(); } void push(LValue lval) { stack.push(lval); } public static Value getMassagedValue() throws ParseException { return lastLValue.getMassagedValue(lastFrameGetter); } public interface GetFrame { StackFrame get() throws IncompatibleThreadStateException; } public static Value evaluate(String expr, VirtualMachine vm, GetFrame frameGetter) throws ParseException, InvocationException, InvalidTypeException, ClassNotLoadedException, IncompatibleThreadStateException { // TODO StringBufferInputStream is deprecated. java.io.InputStream in = new java.io.StringBufferInputStream(expr); ExpressionParser parser = new ExpressionParser(in); parser.vm = vm; parser.frameGetter = frameGetter; Value value = null; parser.Expression(); lastFrameGetter = frameGetter; lastLValue = parser.pop(); return lastLValue.getValue(); } public static void main(String args[]) { ExpressionParser parser; System.out.print("Java Expression Parser: "); if (args.length == 0) { System.out.println("Reading from standard input . . ."); parser = new ExpressionParser(System.in); } else if (args.length == 1) { System.out.println("Reading from file " + args[0] + " . . ."); try { parser = new ExpressionParser(new java.io.FileInputStream(args[0])); } catch (java.io.FileNotFoundException e) { System.out.println("Java Parser Version 1.0.2: File " + args[0] + " not found."); return; } } else { System.out.println("Usage is one of:"); System.out.println(" java ExpressionParser < inputfile"); System.out.println("OR"); System.out.println(" java ExpressionParser inputfile"); return; } try { parser.Expression(); System.out.print("Java Expression Parser: "); System.out.println("Java program parsed successfully."); } catch (ParseException e) { System.out.print("Java Expression Parser: "); System.out.println("Encountered errors during parse."); } } } PARSER_END(ExpressionParser) SKIP : /* WHITE SPACE */ { " " | "\t" | "\n" | "\r" | "\f" } SPECIAL_TOKEN : /* COMMENTS */ { <SINGLE_LINE_COMMENT: "//" (~["\n","\r"])* ("\n"|"\r"|"\r\n")> | <FORMAL_COMMENT: "/**" (~["*"])* "*" ("*" | (~["*","/"] (~["*"])* "*"))* "/"> | <MULTI_LINE_COMMENT: "/*" (~["*"])* "*" ("*" | (~["*","/"] (~["*"])* "*"))* "/"> } TOKEN : /* RESERVED WORDS AND LITERALS */ { < ABSTRACT: "abstract" > | < BOOLEAN: "boolean" > | < BREAK: "break" > | < BYTE: "byte" > | < CASE: "case" > | < CATCH: "catch" > | < CHAR: "char" > | < CLASS: "class" > | < CONST: "const" > | < CONTINUE: "continue" > | < _DEFAULT: "default" > | < DO: "do" > | < DOUBLE: "double" > | < ELSE: "else" > | < EXTENDS: "extends" > | < FALSE: "false" > | < FINAL: "final" > | < FINALLY: "finally" > | < FLOAT: "float" > | < FOR: "for" > | < GOTO: "goto" > | < IF: "if" > | < IMPLEMENTS: "implements" > | < IMPORT: "import" > | < INSTANCEOF: "instanceof" > | < INT: "int" > | < INTERFACE: "interface" > | < LONG: "long" > | < NATIVE: "native" > | < NEW: "new" > | < NULL: "null" > | < PACKAGE: "package"> | < PRIVATE: "private" > | < PROTECTED: "protected" > | < PUBLIC: "public" > | < RETURN: "return" > | < SHORT: "short" > | < STATIC: "static" > | < SUPER: "super" > | < SWITCH: "switch" > | < SYNCHRONIZED: "synchronized" > | < THIS: "this" > | < THROW: "throw" > | < THROWS: "throws" > | < TRANSIENT: "transient" > | < TRUE: "true" > | < TRY: "try" > | < VOID: "void" > | < VOLATILE: "volatile" > | < WHILE: "while" > } TOKEN : /* LITERALS */ { < INTEGER_LITERAL: <DECIMAL_LITERAL> (["l","L"])? | <HEX_LITERAL> (["l","L"])? | <OCTAL_LITERAL> (["l","L"])? > | < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* > | < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ > | < #OCTAL_LITERAL: "0" (["0"-"7"])* > | < FLOATING_POINT_LITERAL: (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? (["f","F","d","D"])? | "." (["0"-"9"])+ (<EXPONENT>)? (["f","F","d","D"])? | (["0"-"9"])+ <EXPONENT> (["f","F","d","D"])? | (["0"-"9"])+ (<EXPONENT>)? ["f","F","d","D"] > | < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ > | < CHARACTER_LITERAL: "'" ( (~["'","\\","\n","\r"]) | ("\\" ( ["n","t","b","r","f","\\","'","\""] | ["0"-"7"] ( ["0"-"7"] )? | ["0"-"3"] ["0"-"7"] ["0"-"7"] ) ) ) "'" > | < STRING_LITERAL: "\"" ( (~["\"","\\","\n","\r"]) | ("\\" ( ["n","t","b","r","f","\\","'","\""] | ["0"-"7"] ( ["0"-"7"] )? | ["0"-"3"] ["0"-"7"] ["0"-"7"] ) ) )* "\"" > } TOKEN : /* IDENTIFIERS */ { < IDENTIFIER: <LETTER> (<LETTER>|<DIGIT>)* > | < #LETTER: [ "\u0024", "\u0041"-"\u005a", "\u005f", "\u0061"-"\u007a", "\u00c0"-"\u00d6", "\u00d8"-"\u00f6", "\u00f8"-"\u00ff", "\u0100"-"\u1fff", "\u3040"-"\u318f", "\u3300"-"\u337f", "\u3400"-"\u3d2d", "\u4e00"-"\u9fff", "\uf900"-"\ufaff" ] > | < #DIGIT: [ "\u0030"-"\u0039", "\u0660"-"\u0669", "\u06f0"-"\u06f9", "\u0966"-"\u096f", "\u09e6"-"\u09ef", "\u0a66"-"\u0a6f", "\u0ae6"-"\u0aef", "\u0b66"-"\u0b6f", "\u0be7"-"\u0bef", "\u0c66"-"\u0c6f", "\u0ce6"-"\u0cef", "\u0d66"-"\u0d6f", "\u0e50"-"\u0e59", "\u0ed0"-"\u0ed9", "\u1040"-"\u1049" ] > } TOKEN : /* SEPARATORS */ { < LPAREN: "(" > | < RPAREN: ")" > | < LBRACE: "{" > | < RBRACE: "}" > | < LBRACKET: "[" > | < RBRACKET: "]" > | < SEMICOLON: ";" > | < COMMA: "," > | < DOT: "." > } TOKEN : /* OPERATORS */ { < ASSIGN: "=" > | < GT: ">" > | < LT: "<" > | < BANG: "!" > | < TILDE: "~" > | < HOOK: "?" > | < COLON: ":" > | < EQ: "==" > | < LE: "<=" > | < GE: ">=" > | < NE: "!=" > | < SC_OR: "||" > | < SC_AND: "&&" > | < INCR: "++" > | < DECR: "--" > | < PLUS: "+" > | < MINUS: "-" > | < STAR: "*" > | < SLASH: "/" > | < BIT_AND: "&" > | < BIT_OR: "|" > | < XOR: "^" > | < REM: "%" > | < LSHIFT: "<<" > | < RSIGNEDSHIFT: ">>" > | < RUNSIGNEDSHIFT: ">>>" > | < PLUSASSIGN: "+=" > | < MINUSASSIGN: "-=" > | < STARASSIGN: "*=" > | < SLASHASSIGN: "/=" > | < ANDASSIGN: "&=" > | < ORASSIGN: "|=" > | < XORASSIGN: "^=" > | < REMASSIGN: "%=" > | < LSHIFTASSIGN: "<<=" > | < RSIGNEDSHIFTASSIGN: ">>=" > | < RUNSIGNEDSHIFTASSIGN: ">>>=" > } /***************************************** * THE JAVA LANGUAGE GRAMMAR STARTS HERE * *****************************************/ /* * Type, name and expression syntax follows. */ void Type() : {} { ( PrimitiveType() | Name() ) ( "[" "]" )* } void PrimitiveType() : {} { "boolean" | "char" | "byte" | "short" | "int" | "long" | "float" | "double" } String Name() : {StringBuffer sb = new StringBuffer();} { <IDENTIFIER> { sb.append(token); } ( LOOKAHEAD(2) "." <IDENTIFIER> { sb.append('.'); sb.append(token); } )* { return sb.toString(); } } void NameList() : {} { Name() ( "," Name() )* } /* * Expression syntax follows. */ void Expression() : {} { LOOKAHEAD( PrimaryExpression() AssignmentOperator() ) Assignment() | ConditionalExpression() } void Assignment() : {} { PrimaryExpression() AssignmentOperator() Expression() { LValue exprVal = pop(); pop().setValue(exprVal); push(exprVal);} } void AssignmentOperator() : {} { "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | ">>>=" | "&=" | "^=" | "|=" } void ConditionalExpression() : {} { ConditionalOrExpression() [ "?" Expression() ":" ConditionalExpression() { LValue falseBranch = pop(); LValue trueBranch = pop(); Value cond = pop().interiorGetValue(); if (cond instanceof BooleanValue) { push(((BooleanValue)cond).booleanValue()? trueBranch : falseBranch); } else { throw new ParseException("Condition must be boolean"); } } ] } void ConditionalOrExpression() : {} { ConditionalAndExpression() ( "||" ConditionalAndExpression() { throw new ParseException("operation not yet supported"); } )* } void ConditionalAndExpression() : {} { InclusiveOrExpression() ( "&&" InclusiveOrExpression() { throw new ParseException("operation not yet supported"); } )* } void InclusiveOrExpression() : {} { ExclusiveOrExpression() ( "|" ExclusiveOrExpression() { throw new ParseException("operation not yet supported"); } )* } void ExclusiveOrExpression() : {} { AndExpression() ( "^" AndExpression() { throw new ParseException("operation not yet supported"); } )* } void AndExpression() : {} { EqualityExpression() ( "&" EqualityExpression() { throw new ParseException("operation not yet supported"); } )* } void EqualityExpression() : {Token tok;} { InstanceOfExpression() ( ( tok = "==" | tok = "!=" ) InstanceOfExpression() { LValue left = pop(); push( LValue.booleanOperation(vm, tok, pop(), left) ); } )* } void InstanceOfExpression() : {} { RelationalExpression() [ "instanceof" Type() { throw new ParseException("operation not yet supported"); } ] }