Design View: Expression Evaluator
NetBeans Debugger
Version: 0.1
Author: Daniel
Prusa
Document History:
[05/06/2001] : version 0.1 : First version of the document.
-
Content:
-
1
The Background
-
2
Overview of Evaluator
-
2.1
Creation of Derivation Tree - Parsing
-
2.2
Evaluation of Derivation Tree
-
3
Implementation Issues
-
3.1
API Proposal
-
3.2
Parsing
-
3.3
Evaluation
-
3.4
Performence
1 The Background
JPDA Debugger module uses Expression Evaluator (abbreviated as Evaluator)
to evaluate Java-syntax expressions assigned to watches and breakpoints'
conditions. The evaluation is performed according to a context given by
a thread
.
Currently used Evaluator is based on com.sun.tools.example.debug.expr.*
example. It suffers from several failures, especially, some basic operation
are not implemented (logical and, or), methods cannot be invoked on instances
of String, length
is not recognized as a field of an array, static fields of this
have to be fully qualified, error messages are not localized, etc. The
Evaluator is unsupported. We have not probably chance to adapt it and modify,
moreover, it would be better to start from a scratch and design an Evaluator
that better suits our requirements.
2 Overview of Evaluator
An input for Evaluator is a string (Java-syntax expression) and a context
(mirror of a debugged virtual machine and a thread).
The process of evaluation consists of two phases:
2.1 Creation of derivation tree - parsing
Lexical and sytax analysis produces a derivation tree according to an input
string. This process does not depend on a context. It is possible to generate
Java expression parser using JavaCC - The Java Parser generator, see
http://www.webgain.com/products/metamata/java_doc.html
for more details, and the appropriate Java grammar.
2.2 Evaluation of derivation tree
Evaluator evaluates a derivation tree recursive. A node of tree (except
leaves) represents an operator, its operands are obtained as the evaluation
of its direct descendants, the evaluation of the node is done by perfoming
the operation on its operands.
Evaluation of expressions should follow Java Language Specification
- http://java.sun.com/docs/books/jls/second_edition/html/j.title.doc.html
.
3 Implementation Issues
3.1 API Proposal
public class DTree
extends java.lang.Object
The class that represents a created derivation tree. It has no public
methods and serves as a reference that can be obtained from Evaluator and
reused to evaluate the expression in some context.
public class ParseException
extends java.lang.Exception
The exception that can be thrown by Evaluator's methods. Indicates
parse and evaluation errors.
public class Evaluator
extends java.lang.Object
The main class that represents the Evalutor.
| Constructor Summary |
| Evaluator |
| Method Summary |
| DTree |
parse(java.lang.String expr) throws ParseException
Parses an expression
and returns its derivation tree. |
| com.sun.jdi.Value |
evaluate(java.lang.String expr, com.sun.jdi.VirtualMachine
vm, com.sun.jdi.ThreadReference thread) throws ParseException
Parses an expression,
evaluates it using a given context and returns the mirror of the result
value in debugged VM. |
| com.sun.jdi.Value |
evaluate(DTree tree, com.sun.jdi.VirtualMachine vm, com.sun.jdi.ThreadReference
thread) throws ParseException
Evaluates an
already parsed expression. |
3.2 Parsing
As already mentioned, Java parser is generated by JavaCC generator. Java
grammar file (
http://www.cobase.cs.ucla.edu/pub/javacc/java/
) can be easily modified to obtain the parser generating a derivation tree
as follows:
All nodes of the tree are instances of classes that extend PValue class.
class PValue
protected Token token; // Token class represents
one lexical element, see JavaCC package
An example: binary operators.
class BinaryOperator extends PValue
private PValue leftOperant, rightOperand;
BinaryOperator (PValue leftOperand, Token operator,
PValue rightOperand)
BinaryOperator class represents any binary operator, id of operator
is given by the token field.
An instance of DTree class returned by Evaluator.parse (String expr)
method encapsulates an instance of PValue class that represents the root
of a derivation tree.
3.3 Evaluation
We add the evaluating method to PValue:
RemoteValue value (Context context)
RemoteValue locally represents value (null, primitive or instance) in
a debugged VM and can be converted to the mirror of the value (com.sun.jdi.Value).
Context class ecapsulates a passed context (VM, thread).
To evaluate a derivation tree means to call value method on the root
of the tree. The whole process is done recursive.
3.4 Performance
We mention two performence related issues here.
The method Evaluator.parse (String expr) is designed to parse an expression
once and evaluate it then in different contexts several times. It should
spare time in case of evaluation of watches and conditions. It is sufficient
if parsing is performed after watch/condition creation only. However, we
cannot expect crucial time reduction (there are ussualy not so many watches/conditions
created).
JavaCC generator can generate two types of parsers - static one (all
its methods and fields are static) and non-static one. The advantage of
the static one is a better performence, however, on the other hand, there
is no possibility to parse more expressions parallely. The question is
if such a capability is required. It is probably sufficient to share one
Evaluator with static synchronized methods.