2 * @(#)Expr.jj 1.2 98/07/09
4 * Copyright 1995-1998 by Sun Microsystems, Inc.,
5 * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
8 * This software is the confidential and proprietary information
9 * of Sun Microsystems, Inc. ("Confidential Information"). You
10 * shall not disclose such Confidential Information and shall use
11 * it only in accordance with the terms of the license agreement
12 * you entered into with Sun.
16 * Modified from java1.0.2.jj: a Java grammar and actions that
17 * implement a front-end.
19 * Copyright (C) 1996, 1997 Sun Microsystems Inc.
21 * Author: Sriram Sankar
26 * Modified to parse and evaluate Java expressions use the Java
29 * Author: Robert Field
33 JAVA_UNICODE_ESCAPE = true;
37 PARSER_BEGIN(ExpressionParser)
39 package jde.debugger.expr;
42 import java.util.Stack;
43 import java.util.List;
44 import java.util.ArrayList;
46 public class ExpressionParser {
48 Stack stack = new Stack();
49 VirtualMachine vm = null;
50 GetFrame frameGetter = null;
53 return (LValue)stack.peek();
57 return (LValue)stack.pop();
60 void push(LValue lval) {
64 public interface GetFrame {
65 StackFrame get() throws IncompatibleThreadStateException;
68 public static Value evaluate(String expr, VirtualMachine vm,
69 GetFrame frameGetter) throws ParseException,
72 ClassNotLoadedException,
73 IncompatibleThreadStateException {
74 // TODO StringBufferInputStream is deprecated.
75 java.io.InputStream in = new java.io.StringBufferInputStream(expr);
76 ExpressionParser parser = new ExpressionParser(in);
78 parser.frameGetter = frameGetter;
81 return parser.pop().getValue();
84 public static void main(String args[]) {
85 ExpressionParser parser;
86 System.out.print("Java Expression Parser: ");
87 if (args.length == 0) {
88 System.out.println("Reading from standard input . . .");
89 parser = new ExpressionParser(System.in);
90 } else if (args.length == 1) {
91 System.out.println("Reading from file " + args[0] + " . . .");
93 parser = new ExpressionParser(new java.io.FileInputStream(args[0]));
94 } catch (java.io.FileNotFoundException e) {
95 System.out.println("Java Parser Version 1.0.2: File " +
96 args[0] + " not found.");
100 System.out.println("Usage is one of:");
101 System.out.println(" java ExpressionParser < inputfile");
102 System.out.println("OR");
103 System.out.println(" java ExpressionParser inputfile");
108 System.out.print("Java Expression Parser: ");
109 System.out.println("Java program parsed successfully.");
110 } catch (ParseException e) {
111 System.out.print("Java Expression Parser: ");
112 System.out.println("Encountered errors during parse.");
118 PARSER_END(ExpressionParser)
121 SKIP : /* WHITE SPACE */
130 SPECIAL_TOKEN : /* COMMENTS */
132 <SINGLE_LINE_COMMENT: "//" (~["\n","\r"])* ("\n"|"\r"|"\r\n")>
133 | <FORMAL_COMMENT: "/**" (~["*"])* "*" ("*" | (~["*","/"] (~["*"])* "*"))* "/">
134 | <MULTI_LINE_COMMENT: "/*" (~["*"])* "*" ("*" | (~["*","/"] (~["*"])* "*"))* "/">
137 TOKEN : /* RESERVED WORDS AND LITERALS */
139 < ABSTRACT: "abstract" >
140 | < BOOLEAN: "boolean" >
148 | < CONTINUE: "continue" >
149 | < _DEFAULT: "default" >
151 | < DOUBLE: "double" >
153 | < EXTENDS: "extends" >
156 | < FINALLY: "finally" >
161 | < IMPLEMENTS: "implements" >
162 | < IMPORT: "import" >
163 | < INSTANCEOF: "instanceof" >
165 | < INTERFACE: "interface" >
167 | < NATIVE: "native" >
170 | < PACKAGE: "package">
171 | < PRIVATE: "private" >
172 | < PROTECTED: "protected" >
173 | < PUBLIC: "public" >
174 | < RETURN: "return" >
176 | < STATIC: "static" >
178 | < SWITCH: "switch" >
179 | < SYNCHRONIZED: "synchronized" >
182 | < THROWS: "throws" >
183 | < TRANSIENT: "transient" >
187 | < VOLATILE: "volatile" >
191 TOKEN : /* LITERALS */
195 <DECIMAL_LITERAL> (["l","L"])?
196 | <HEX_LITERAL> (["l","L"])?
197 | <OCTAL_LITERAL> (["l","L"])?
200 < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
202 < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
204 < #OCTAL_LITERAL: "0" (["0"-"7"])* >
206 < FLOATING_POINT_LITERAL:
207 (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? (["f","F","d","D"])?
208 | "." (["0"-"9"])+ (<EXPONENT>)? (["f","F","d","D"])?
209 | (["0"-"9"])+ <EXPONENT> (["f","F","d","D"])?
210 | (["0"-"9"])+ (<EXPONENT>)? ["f","F","d","D"]
213 < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
217 ( (~["'","\\","\n","\r"])
219 ( ["n","t","b","r","f","\\","'","\""]
220 | ["0"-"7"] ( ["0"-"7"] )?
221 | ["0"-"3"] ["0"-"7"] ["0"-"7"]
230 ( (~["\"","\\","\n","\r"])
232 ( ["n","t","b","r","f","\\","'","\""]
233 | ["0"-"7"] ( ["0"-"7"] )?
234 | ["0"-"3"] ["0"-"7"] ["0"-"7"]
242 TOKEN : /* IDENTIFIERS */
244 < IDENTIFIER: <LETTER> (<LETTER>|<DIGIT>)* >
285 TOKEN : /* SEPARATORS */
298 TOKEN : /* OPERATORS */
324 | < RSIGNEDSHIFT: ">>" >
325 | < RUNSIGNEDSHIFT: ">>>" >
326 | < PLUSASSIGN: "+=" >
327 | < MINUSASSIGN: "-=" >
328 | < STARASSIGN: "*=" >
329 | < SLASHASSIGN: "/=" >
330 | < ANDASSIGN: "&=" >
332 | < XORASSIGN: "^=" >
333 | < REMASSIGN: "%=" >
334 | < LSHIFTASSIGN: "<<=" >
335 | < RSIGNEDSHIFTASSIGN: ">>=" >
336 | < RUNSIGNEDSHIFTASSIGN: ">>>=" >
340 /*****************************************
341 * THE JAVA LANGUAGE GRAMMAR STARTS HERE *
342 *****************************************/
345 * Type, name and expression syntax follows.
351 ( PrimitiveType() | Name() ) ( "[" "]" )*
354 void PrimitiveType() :
376 {StringBuffer sb = new StringBuffer();}
378 <IDENTIFIER> { sb.append(token); }
379 ( LOOKAHEAD(2) "." <IDENTIFIER> { sb.append('.'); sb.append(token); }
381 { return sb.toString(); }
394 * Expression syntax follows.
400 LOOKAHEAD( PrimaryExpression() AssignmentOperator() )
403 ConditionalExpression()
409 PrimaryExpression() AssignmentOperator() Expression()
410 { LValue exprVal = pop(); pop().setValue(exprVal); push(exprVal);}
413 void AssignmentOperator() :
416 "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | ">>>=" | "&=" | "^=" | "|="
419 void ConditionalExpression() :
422 ConditionalOrExpression()
423 [ "?" Expression() ":" ConditionalExpression()
424 { LValue falseBranch = pop(); LValue trueBranch = pop();
425 Value cond = pop().interiorGetValue();
426 if (cond instanceof BooleanValue) {
427 push(((BooleanValue)cond).booleanValue()?
428 trueBranch : falseBranch);
430 throw new ParseException("Condition must be boolean");
436 void ConditionalOrExpression() :
439 ConditionalAndExpression()
440 ( "||" ConditionalAndExpression()
441 { throw new ParseException("operation not yet supported"); }
445 void ConditionalAndExpression() :
448 InclusiveOrExpression()
449 ( "&&" InclusiveOrExpression()
450 { throw new ParseException("operation not yet supported"); }
454 void InclusiveOrExpression() :
457 ExclusiveOrExpression()
458 ( "|" ExclusiveOrExpression()
459 { throw new ParseException("operation not yet supported"); }
463 void ExclusiveOrExpression() :
467 ( "^" AndExpression()
468 { throw new ParseException("operation not yet supported"); }
472 void AndExpression() :
476 ( "&" EqualityExpression()
477 { throw new ParseException("operation not yet supported"); }
481 void EqualityExpression() :
484 InstanceOfExpression()
485 ( ( tok = "==" | tok = "!=" ) InstanceOfExpression()
486 { LValue left = pop();
487 push( LValue.booleanOperation(vm, tok, pop(), left) ); }
491 void InstanceOfExpression() :
494 RelationalExpression()
495 [ "instanceof" Type()
496 { throw new ParseException("operation not yet supported"); }
500 void RelationalExpression() :
504 ( ( tok = "<" | tok = ">" | tok = "<=" | tok = ">=" ) ShiftExpression()
505 { LValue left = pop();
506 push( LValue.booleanOperation(vm, tok, pop(), left) ); }
510 void ShiftExpression() :
514 ( ( "<<" | ">>" | ">>>" ) AdditiveExpression()
515 { throw new ParseException("operation not yet supported"); }
519 void AdditiveExpression() :
522 MultiplicativeExpression()
523 ( ( tok = "+" | tok = "-" ) MultiplicativeExpression()
524 { LValue left = pop();
525 push( LValue.operation(vm, tok, pop(), left) ); }
529 void MultiplicativeExpression() :
533 ( ( tok = "*" | tok = "/" | tok = "%" ) UnaryExpression()
534 { LValue left = pop();
535 push( LValue.operation(vm, tok, pop(), left) ); }
539 void UnaryExpression() :
542 ( "+" | "-" ) UnaryExpression()
543 { throw new ParseException("operation not yet supported"); }
545 PreIncrementExpression()
547 PreDecrementExpression()
549 UnaryExpressionNotPlusMinus()
552 void PreIncrementExpression() :
555 "++" PrimaryExpression()
556 { throw new ParseException("operation not yet supported"); }
559 void PreDecrementExpression() :
562 "--" PrimaryExpression()
563 { throw new ParseException("operation not yet supported"); }
566 void UnaryExpressionNotPlusMinus() :
569 ( "~" | "!" ) UnaryExpression()
570 { throw new ParseException("operation not yet supported"); }
572 LOOKAHEAD( CastLookahead() )
578 // This production is to determine lookahead only. The LOOKAHEAD specifications
579 // below are not used, but they are there just to indicate that we know about
581 void CastLookahead() :
587 LOOKAHEAD("(" Name() "[")
590 "(" Name() ")" ( "~" | "!" | "(" | <IDENTIFIER> | "this" | "super" | "new" | Literal() )
593 void PostfixExpression() :
598 { throw new ParseException("operation not yet supported"); }
602 void CastExpression() :
606 "(" PrimitiveType() ( "[" "]" )* ")" UnaryExpression()
608 "(" Name() ( "[" "]" )* ")" UnaryExpressionNotPlusMinus()
611 void PrimaryExpression() :
614 PrimaryPrefix() ( PrimarySuffix() )*
617 void PrimaryPrefix() :
623 { push(LValue.makeName(vm, frameGetter, name)); }
626 { push(LValue.makeThisObject(vm, frameGetter, token)); }
628 "super" "." <IDENTIFIER>
629 { throw new ParseException("operation not yet supported"); }
633 AllocationExpression()
636 void PrimarySuffix() :
640 { LValue index = pop();
641 push(pop().arrayElementLValue(index)); }
644 { push(pop().memberLValue(frameGetter, token.image)); }
646 argList = Arguments()
647 { peek().invokeWith(argList); }
654 { push(LValue.makeInteger(vm, token)); }
656 <FLOATING_POINT_LITERAL>
657 { push(LValue.makeFloat(vm, token)); }
660 { push(LValue.makeCharacter(vm, token)); }
663 { push(LValue.makeString(vm, token)); }
666 { push(LValue.makeBoolean(vm, token)); }
669 { push(LValue.makeNull(vm, token)); }
672 void BooleanLiteral() :
687 {List argList = new ArrayList();}
689 "(" [ ArgumentList(argList) ] ")"
693 void ArgumentList(List argList) :
696 Expression() {argList.add(pop().interiorGetValue());}
697 ( "," Expression() {argList.add(pop().interiorGetValue());} )*
700 void AllocationExpression() :
701 {List argList; String className;}
704 "new" PrimitiveType() ArrayDimensions()
706 "new" className = Name() ( argList = Arguments()
707 { push(LValue.makeNewObject(vm, frameGetter, className, argList)); }
709 { throw new ParseException("operation not yet supported"); }
714 * The second LOOKAHEAD specification below is to parse to PrimarySuffix
715 * if there is an expression between the "[...]".
717 void ArrayDimensions() :
720 ( LOOKAHEAD(2) "[" Expression() "]" )+ ( LOOKAHEAD(2) "[" "]" )*