alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (Expr.jj)

This example Java source code file (Expr.jj) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

exponent, expression, expressionparser, getframe, identifier, jdi, list, lookahead, lvalue, name, parseexception, primaryexpression, primitivetype, token, unaryexpression, util

The Expr.jj Java example source code

/*
 * 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:
      [
       "\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"); }
        ]
}

void RelationalExpression() :
{Token tok;}
{
  ShiftExpression() 
        ( ( tok = "<" | tok = ">" | tok = "<=" | tok = ">=" ) ShiftExpression()
                { LValue left = pop(); 
                  push( LValue.booleanOperation(vm, tok, pop(), left) ); }
         )*
}

void ShiftExpression() :
{}
{
  AdditiveExpression() 
        ( ( "<<" | ">>" | ">>>" ) AdditiveExpression() 
                        { throw new ParseException("operation not yet supported"); }
        )*
}

void AdditiveExpression() :
{Token tok;}
{
  MultiplicativeExpression() 
        ( ( tok = "+" | tok = "-" ) MultiplicativeExpression() 
                { LValue left = pop(); 
                  push( LValue.operation(vm, tok, pop(), left, frameGetter) ); }
        )*
}

void MultiplicativeExpression() :
{Token tok;}
{
  UnaryExpression() 
        ( ( tok = "*" | tok = "/" | tok = "%" ) UnaryExpression()
                { LValue left = pop(); 
                  push( LValue.operation(vm, tok, pop(), left, frameGetter) ); }
        )*
}

void UnaryExpression() :
{}
{
  ( "+" | "-" ) UnaryExpression()
                        { throw new ParseException("operation not yet supported"); }
|
  PreIncrementExpression()
|
  PreDecrementExpression()
|
  UnaryExpressionNotPlusMinus()
}

void PreIncrementExpression() :
{}
{
  "++" PrimaryExpression()
                        { throw new ParseException("operation not yet supported"); }
}

void PreDecrementExpression() :
{}
{
  "--" PrimaryExpression()
                        { throw new ParseException("operation not yet supported"); }
}

void UnaryExpressionNotPlusMinus() :
{}
{
  ( "~" | "!" ) UnaryExpression()
                        { throw new ParseException("operation not yet supported"); }
|
  LOOKAHEAD( CastLookahead() )
  CastExpression()
|
  PostfixExpression()
}

// This production is to determine lookahead only.  The LOOKAHEAD specifications
// below are not used, but they are there just to indicate that we know about
// this.
void CastLookahead() :
{}
{
  LOOKAHEAD(2)
  "(" PrimitiveType()
|
  LOOKAHEAD("(" Name() "[")
  "(" Name() "[" "]"
|
  "(" Name() ")" ( "~" | "!" | "(" | <IDENTIFIER> | "this" | "super" | "new" | Literal() )
}

void PostfixExpression() :
{}
{
  PrimaryExpression() 
        [ "++" | "--" 
                        { throw new ParseException("operation not yet supported"); }
        ]
}

void CastExpression() :
{}
{
  LOOKAHEAD(2)
  "(" PrimitiveType() ( "[" "]" )* ")" UnaryExpression()
|
  "(" Name() ( "[" "]" )* ")" UnaryExpressionNotPlusMinus()
}

void PrimaryExpression() :
{}
{
  PrimaryPrefix() ( PrimarySuffix() )*
}

void PrimaryPrefix() :
{String name;}
{
  Literal()
|
  name = Name()
                        { push(LValue.makeName(vm, frameGetter, name)); }
|
  "this"
                        { push(LValue.makeThisObject(vm, frameGetter, token)); }
|
  "super" "." <IDENTIFIER>
                        { throw new ParseException("operation not yet supported"); }
|
  "(" Expression() ")"
|
  AllocationExpression()
}

void PrimarySuffix() :
{List argList;}
{
  "[" Expression() "]"  
                        { LValue index = pop();
                          push(pop().arrayElementLValue(index)); }
|
  "." <IDENTIFIER>
                        { push(pop().memberLValue(frameGetter, token.image)); }
|
  argList = Arguments()
                        { peek().invokeWith(argList); }
}

void Literal() :
{}
{
  <INTEGER_LITERAL>
                        { push(LValue.makeInteger(vm, token)); }
|
  <FLOATING_POINT_LITERAL>
                        { push(LValue.makeFloat(vm, token)); }
|
  <CHARACTER_LITERAL>
                        { push(LValue.makeCharacter(vm, token)); }
|
  <STRING_LITERAL>
                        { push(LValue.makeString(vm, token)); }
|
  BooleanLiteral()
                        { push(LValue.makeBoolean(vm, token)); }
|
  NullLiteral()
                        { push(LValue.makeNull(vm, token)); }
}

void BooleanLiteral() :
{}
{
  "true" 
|
  "false"
}

void NullLiteral() :
{}
{
  "null"
}

List Arguments() :
{List argList = new ArrayList();}
{
  "(" [ ArgumentList(argList) ] ")"
  { return argList; }
}

void ArgumentList(List argList) :
{}
{
  Expression() {argList.add(pop().interiorGetValue());}
  ( "," Expression() {argList.add(pop().interiorGetValue());} )*
}

void AllocationExpression() :
{List argList; String className;}
{
  LOOKAHEAD(2)
  "new" PrimitiveType() ArrayDimensions()
|
  "new" className = Name() ( argList = Arguments() 
                        { push(LValue.makeNewObject(vm, frameGetter, className, argList)); }
                           | ArrayDimensions() 
                        { throw new ParseException("operation not yet supported"); }
			   )
}

/*
 * The second LOOKAHEAD specification below is to parse to PrimarySuffix
 * if there is an expression between the "[...]".
 */
void ArrayDimensions() :
{}
{
  ( LOOKAHEAD(2) "[" Expression() "]" )+ ( LOOKAHEAD(2) "[" "]" )*
}

Other Java examples (source code examples)

Here is a short list of links related to this Java Expr.jj source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.