jjackson2004
asked on
parsing an input express creating an expression tree with the tokens, then use a postorder tree transversal to extrace a postifx expression
Trying to do this program but after all my research on expression trees I am still drawing a blank. Can anyone get me started in the right direction. First of all I need a class to use for the tree.
And then some hints if not outright direction on how to proceed. I have code from other programs I have done to evaluate the infix expression for validity, but then I need to build the tree. I understand the basic concept for building a tree (graphically in that I can trace the logic on paper), but not how to do it programatically(?). I have search EE for this and there are 10 hits, but they did not help me.
Thanks in advance for your assistance. I will be glad to break this into several questions for additional points if desired.
And then some hints if not outright direction on how to proceed. I have code from other programs I have done to evaluate the infix expression for validity, but then I need to build the tree. I understand the basic concept for building a tree (graphically in that I can trace the logic on paper), but not how to do it programatically(?). I have search EE for this and there are 10 hits, but they did not help me.
Thanks in advance for your assistance. I will be glad to break this into several questions for additional points if desired.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Also, as I look over this code, I have a question. Why are the left and right variables in:
class BinOpNode extends ExpNode {
// Represents a node that holds an operator.
char op; // The operator.
ExpNode left; // The left operand.
ExpNode right; // The right operand.
Why are they of type ExpNode? Why are they not ConstNode?
class BinOpNode extends ExpNode {
// Represents a node that holds an operator.
char op; // The operator.
ExpNode left; // The left operand.
ExpNode right; // The right operand.
Why are they of type ExpNode? Why are they not ConstNode?
ASKER
Is by it being ExpNode, it can hold either the BinOpNode and ConstNode?
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I have to accept an 'x' in the infix expression. Currently I can't handle it with the nodes I have. Should I create a third node class that extends the first one. This one will only hold 'x'. Should I just hard code it that way? And so my operand stack would hold either the binopnode or the xnode?
ASKER
I tried to create a third node, but it violated the abstract value method. So now I am stuck. Can someone help me with the logic.
let's say i use (4 + 5/2) as infix string.
I parse the '(' and put on a stack (what stack should I use here)
next the 4 is pushed on a different stack.
'+' is put on an operand stack.
5 is pushed on number stack
/ is pushed on operand stack
2 is pushed on number stack
) causes me to start popping things off stack.
now I should be creating the expression tree, but how?
let's say i use (4 + 5/2) as infix string.
I parse the '(' and put on a stack (what stack should I use here)
next the 4 is pushed on a different stack.
'+' is put on an operand stack.
5 is pushed on number stack
/ is pushed on operand stack
2 is pushed on number stack
) causes me to start popping things off stack.
now I should be creating the expression tree, but how?
ASKER
ok, I have the following code, but now I need to change the passed variable to expTree from scanner to String. Also want to change from double to int. for the string, what do I use instead of hasNextInt(),nextInt() and next()?
public class ExpressionTree
{
private static class TreeNode
{
private final boolean leaf; // ?Is this a leaf? else internal
private final char op; // For an internal node, the operator
private double value; // For a leaf, the value
private TreeNode left, // Left subexpression for an internal node
right; // Right subexpression
// Bare-bones constructor
private TreeNode ( boolean leaf, char op, double value )
{
this.leaf = leaf;
this.op = op;
this.value = value;
this.left = null; // Empty to start
this.right = null;
}
// For leaf nodes, show the value; for internal, the operator.
public String toString() // To override Object.toString, must be public.
{ return leaf ? Double.toString(value) : Character.toString(op) ; }
}
TreeNode root = null;
public ExpressionTree ( Scanner input )
{ root = build(input); }
/**
* Based on a white-space delimited prefix expression, build the
* corresponding binary expression tree.
* @param input The scanner with the expression
* @return reference to the corresponding binary expression tree
*/
private TreeNode build ( Scanner input )
{
boolean leaf;
String token;
double value;
TreeNode node;
leaf = input.hasNextDouble();
if ( leaf )
{
value = input.nextDouble();
node = new TreeNode ( leaf, '\0', value );
}
else
{
token = input.next();
node = new TreeNode ( leaf, token.charAt(0), 0.0 );
node.left = build ( input );
node.right = build ( input );
}
return node;
}
public class ExpressionTree
{
private static class TreeNode
{
private final boolean leaf; // ?Is this a leaf? else internal
private final char op; // For an internal node, the operator
private double value; // For a leaf, the value
private TreeNode left, // Left subexpression for an internal node
right; // Right subexpression
// Bare-bones constructor
private TreeNode ( boolean leaf, char op, double value )
{
this.leaf = leaf;
this.op = op;
this.value = value;
this.left = null; // Empty to start
this.right = null;
}
// For leaf nodes, show the value; for internal, the operator.
public String toString() // To override Object.toString, must be public.
{ return leaf ? Double.toString(value) : Character.toString(op) ; }
}
TreeNode root = null;
public ExpressionTree ( Scanner input )
{ root = build(input); }
/**
* Based on a white-space delimited prefix expression, build the
* corresponding binary expression tree.
* @param input The scanner with the expression
* @return reference to the corresponding binary expression tree
*/
private TreeNode build ( Scanner input )
{
boolean leaf;
String token;
double value;
TreeNode node;
leaf = input.hasNextDouble();
if ( leaf )
{
value = input.nextDouble();
node = new TreeNode ( leaf, '\0', value );
}
else
{
token = input.next();
node = new TreeNode ( leaf, token.charAt(0), 0.0 );
node.left = build ( input );
node.right = build ( input );
}
return node;
}
ASKER
Has this question been abandoned by the experts? Should I even bother continue to ask questions. T
he last three entries are mine.
I have another question that is now the relevant question.
he last three entries are mine.
I have another question that is now the relevant question.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
...and when you consider a question as abandoned or you are not satisfied by the answers you can delete it.
ASKER
Also, is there a way to make an interface for the two stacks and then extend them. If so, would you mind showing me the proper coding? No. Skip that for now, I need to get this up and running to show very soon.
Thanks
Made a test program while I build the different parts.
**************************
public class test {
public static void main(String[] args) {
abstract class ExpNode {
// Represents a node of any type in an expression tree.
abstract int value(); // Return the value of this node.
} // end class ExpNode
class ConstNode extends ExpNode {
// Represents a node that holds a number.
int number; // The number in the node.
ConstNode( int val ) {
// Constructor. Create a node to hold val.
number = val;
}
int value() {
// The value is just the number that the node holds.
return number;
}
} // end class ConstNode
class BinOpNode extends ExpNode {
// Represents a node that holds an operator.
char op; // The operator.
ExpNode left; // The left operand.
ExpNode right; // The right operand.
BinOpNode( char op, ExpNode left, ExpNode right ) {
// Constructor. Create a node to hold the given data.
this.op = op;
this.left = left;
this.right = right;
}
int value() {
// To get the value, compute the value of the left and
// right operands, and combine them with the operator.
int leftVal = left.value();
int rightVal = right.value();
switch ( op ) {
case '+': return leftVal + rightVal;
case '-': return leftVal - rightVal;
case '*': return leftVal * rightVal;
case '/': return leftVal / rightVal;
default: return 0; // Bad operator.
}
}
} // end class BinOpNode
// stack class to handle postfix calculation temporary storage
class operandStack {
private int maxSize;
private ConstNode[] stackArray;
private int top;
public operandStack(int size) {
maxSize = size;
stackArray = new ConstNode[maxSize];
top = -1;
}
public void push(ConstNode j) {
stackArray[++top] = j;
}
public ConstNode pop() {
return stackArray[top--];
}
public ConstNode peek() {
return stackArray[top];
}
public boolean isEmpty() {
return (top == -1);
}
public boolean isFull() {
return (top == maxSize - 1);
}
public int size() {
return top + 1;
}
public ConstNode peekN(int n) {
return stackArray[n];
}
}
class operatorStack {
private int maxSize;
private BinOpNode[] stackArray;
private int top;
public operatorStack(int size) {
maxSize = size;
stackArray = new BinOpNode[maxSize];
top = -1;
}
public void push(BinOpNode j) {
stackArray[++top] = j;
}
public BinOpNode pop() {
return stackArray[top--];
}
public BinOpNode peek() {
return stackArray[top];
}
public boolean isEmpty() {
return (top == -1);
}
public boolean isFull() {
return (top == maxSize - 1);
}
public int size() {
return top + 1;
}
public BinOpNode peekN(int n) {
return stackArray[n];
}
}
}
}