How to get binary subexpressions with javaparser - java

I am using javaparser to parse the AST for Java source files.
I would like to get all binary subexpressions in the source code as individual nodes.
Here is the source code I am parsing:
class MyClass {
public MyClass() {
double x = (4 / 10.0) + 15;
}
}
I implemented a Visitor that accepts the built-in BinaryExp type, but the only node that it finds contains the binary expression:
(4 / 10.0) + 15
Is there a way to visit the subexpression "(4 / 10.0)" as well?
I tried getting the full expression's "left operand", but it is of type Expression, and not BinaryExpr as I expected.
Any help would be appreciated.

The left operand cannot be of actual type Expression because Expression is an abstract class.
You can check the actual type by checking binEx.getLeft() instanceof BinaryExp.If this evaluates true, you can cast to BinaryExpression.
But probably it evaluates false and the node is of type EnclosedExpr (parentheses). Then the binary expression is the child of the left node
This will probably not solve the whole problem. I think you missed to apply the visitor to the child nodes. You have to adjust visit(BinaryExpr n, A arg):
if you use a GenericVisitorAdaptor you will have to call super.visit(n,arg)
if you wrote your own adaptor you will have to call accept(this, arg) on each child.

Related

How do I generate a list of commands to evaluate a mathematical expression on a stack machine using parse trees and a tokenizer?

So I am trying to create a CalcParser class that, when given a mathematical expression, generates a string containing commands to evaluate the expression on a stack machine. For example, 1+2*3 should output:
push 1.0
push 2.0
push 3.0
multiply
add
Also, parentheses must be observed. So (1+2)*3 should output:
push 1.0
push 2.0
add
push 3.0
multiply
I am working with a pre-existing CalcLexer class that holds the string being parsed and converts it into a series of tokens using java.util.StringTokenizer. The only piece of information necessary from this class is the operators \t\n\r+-*/() and whitespace are also considered individual tokens.
Here is my question. If I were using parse trees to generate the output code, how would I take into account the parentheses since an expression inside parentheses will always be done first? Here is what I have so far for the parseRootexp() method, and I have a feeling I'm a bit off:
private double value;
private CalcLexer lexer = new CalcLexer();
private void parseRootexp(){
if (lexer.nextToken() == '('){
match('(');
do{
lexer.nextToken();
if (lexer.nextToken() == CalcLexer.NUMBER_TOKEN){
value = lexer.getNum();
System.out.println("push " + value + "\n");
}
} while (lexer.nextToken() != ')');
}
}
The match(int token) method is used simply to match the current token with an allowable terminal symbol. If not, an error is returned. I know this is far from what I want ideally, but what I need is something to push me in the right direction. Thanks in advance.

Replacing Mathematical Operators with Variable Java

Currently trying to do a reverse polish calculator for one of my Uni homework tasks.
I have the program working fine when using a bunch of if/else statements to work out which operator was typed in and do the mathematical operation normally like num1+num2.
This is beyond the homework task we were set but what I'm trying to do now is replace the operator with a variable for example: "num1 + num2" would become "num1 variable num2" where variable equals "+" etc.
Is there a way to do this in Java?
Thanks in advance
Since you are interested in going beyond the scope of the training material, and assuming you've learned about interfaces already, I believe what you are looking for is a binary expression tree (that wikipedia article actually explains it good).
Basically, you create an interface Expression with a double compute() method. There will be two types of implementing classes:
Operand: Constant and Variable.
Operator: Plus, Minus, Multiply, Divide. Each will have two Expression fields: left and right.
Your text expression is then parsed into the expression tree:
// input: "num1 + num2 * 3"
// result expression tree will be built by parser using:
Expression a = new Variable("num1");
Expression b = new Variable("num2");
Expression c = new Constant(3);
Expression d = new Multiply(b, c);
Expression e = new Plus(a, d);
Map<String, Double> variables = /*defined elsewhere*/;
double result = e.compute(variables);
Your new assignment, should you choose to accept it, will be to write the expression classes and a parser to build the expression tree from a text expression.
Hope this will encourage you to go way beyond the training material, having some fun while playing.
First you can use a switch on String rather than if-then-else chain. Another way is to build a static final Map (E.g. HashMap) from String to Function. The strings are the operators. The Functions do the operation. In Java 8 you can give the functions as lambdas. I only have access through a phone right now so can't show code. Your question will be much better received if you add code showing what you mean.

Identifying the types of parameters passed to methods using the AST of the JDT

I am using the AST of the JDT to parse Java files and am currently trying to figure out how to identify the type of the parameters passed to methods during method invocation.
Currently I use the VariableDeclarationFragment to store the type of any variable in a method in a HashMap. When a method invocation occurs (identified using MethodInvocation), I search for the variable passed as a parameter in the HashMap so as to determine its type.
So for example if I have something like:
int x = 7;
M1(x);
in the HashMap I store x which maps to int. When the method M1 is invoked I check what is the type of x and use it as needed.
My problem is that this does not work in invocations like
M1(7)
Is there a way of determining the type of '7' using the AST?
As you mentioned in your comments you have to use resolveTypeBindings().
M1(7)
Will be represented as:
ExpressionStatement [655, 6]
EXPRESSION
MethodInvocation [655, 5]
> (Expression) type binding: void
> method binding: Main.M1(int)
ResolvedTypeInferredFromExpectedType: false
Boxing: false; Unboxing: false
ConstantExpressionValue: null
EXPRESSION: null
TYPE_ARGUMENTS (0)
NAME
ARGUMENTS (1)
NumberLiteral [658, 1]
> (Expression) type binding: int
Boxing: false; Unboxing: false
ConstantExpressionValue: 7
TOKEN: '7'
So by having ExpressionStatement you will find out that it has Expression which is MethodInvocation then you can get its arguments and it will be NumberLiteral and then you can use resolveTypeBindings()
Note: in comments you were told to check if it's NumberLiteral and assume that it's number. Yes this is true it's a number but you won't know its type; whether it's int or double or something else.
P.S. The tree representation above was made using ASTView plug-in which is extremely helpful working with AST, so I recommend to get it if you don't have it already.

Binary Tree Postfix Calculator

I'm making a Postfix calculator where I must use stack objects and a Binary tree during the translation of an expression from infix to a parse tree during the evaluation of a postfix expression.
Can someone please translate?
I have developed a postfix calculator method and I've developed a method that changes an expression from infix to postfix, but I don't understand what I am being asked to do. I can enter an expression in infix and calculate it fine as well as convert it to postfix, but I cannot determine what exactly I am being asked to create here.
An example of how to essentially do this in pseudocode would be very helpful or just an explanation of how to store a mathematical expression into a binary tree as well as how to evaluate an expression in a binary tree with stack into a parse tree.
I'll also say I'm a little unsure what a parse tree is.
Any explanation would be very much appreciated.
It is an assignment for a class, so it can be seen here if this was inadequate information: http://www.cs.gsu.edu/jbhola/csc3410/Spring13/assign6_expre_tree.html
My main point here is I just don't quite understand what I'm supposed to do or how I'm supposed to do it. We weren't taught how to program any of this and we lack a textbook so I'm just kind of blindly trying to wrap my head around the whole project :/
Imagine you have a node like AddNode which has two values
class AddNode {
final double a, b;
double value() {
return // how could you return the value of this node?
}
}
Making it more generic
interface Node { double value(); }
class AddNode implements Node {
final Node a, b;
double value() {
return // something which gives the value of this node.
}
}

Trying to understand parsers

I'm trying to use JavaCC to build a simple command line calculator that can handle a variety of expressions. While there are plenty of tutorials out there on how to write grammars, none that I've seen so far explain what happens afterwards.
What I understand right now is that after a string is passed into the parser, it's split into a tokens and turned into a parse tree. What happens next? Do I traverse through the parse tree doing a bunch of if-else string comparisons on the contents of each node and then perform the appropriate function?
I highly suggest you watch Scott Stanchfield's ANTLR 3.x tutorials. Even if you don't end up using ANTLR, which may be overkill for your project but I doubt it, you will learn a lot by watching him go through the thought process.
In general the process is...
Build a lexer to understand your tokens
Build a parser that can validate and understand and organize the input into an abstract syntax tree (AST) which should represent a simplified/easy-to-work-with version of your syntax
Run any calculation based on the AST
You need to actually compile or interpret it according to what you need..
For a calculator you just need to visit the tree recursively and evaluate the parsed tree while with a more complex language you would have to translate it to an intermediate language which is assembly-like but keeps abstraction from the underlying architecture.
Of course you could develop your own simple VM that is able to execute a set of instruction in which your language compiles but it would be overkill in your case.. just visit the parse tree. Something like:
enum Operation {
PLUS, MINUS
}
interface TreeNode {
float eval();
}
class TreeFloat implements TreeNode {
float val;
float eval() { return val; }
}
class TreeBinaryOp implements TreeNode {
TreeNode first;
TreeNode second;
Operation op;
float eval() {
if (op == PLUS)
return first.eval()+second.eval();
}
Then you just call the eval function on the root of the tree. A semantic checking could be needed (with the construction of a symbol table too if you plan to have variables or whatever).
Do I traverse through the parse tree doing a bunch of if-else string comparisons on the contents of each node and then perform the appropriate function?
No, there's no need to build a parse tree to implement a calculator. In the parts of the code where you would create a new node object, just do the calculations and return a number.
JavaCC allows you to choose any return type for a production, so just have your's return numbers.
Some parser generators (such as YACC) let you put actions within the grammar so when you apply a certain production you can also apply a defined action during that production.
E.g. in YACC:
E: NUM + NUM {$$ = $1.value + $2.value};
would add the values of NUM and return the result to the E non-terminal.
Not sure what JavaCC lets you do.

Categories