Creating a String expression when given an expression tree - java

I am having trouble creating a String expression when given an expression tree. If my expression tree looks like this (in the output console):
(*(+(5)(-(2)(3)))(6))
How do I create a method that goes through this to create an expression that is in normal format? For example, like this:
(2 - 3 + 5) * 6
Should I be working with the actual expression tree or the String orientation of the expression tree (as shown above as: (*(+(5)(-(2)(3)))(6))).

You should use prefix to infix conversion algorithm.
It's because your expression tree string is in prefix form and you want it in infix form.
You can remove all the braces in input string. That way it will be easier.

About that I advise you to read these documents.
Shunting-yard algorithm: https://en.wikipedia.org/wiki/Shunting-yard_algorithm
This algorithm is about 'tokens' stacking according to their "precedence power", per example, a function between parenthesis comes first. As for that read these:
https://en.wikipedia.org/wiki/Order_of_operations
http://introcs.cs.princeton.edu/java/11precedence/ (This one is specific for programming)
I hope I have helped.
Have a nice day. :)

Related

How to read text between multi-level parenthetical expressions

I am trying to parse through text to see if it is a valid expression. I am faced with the following problem.
((5*4) + 3) is a valid expression.
How would I parse this to allow me to analyze what is in one level of parentheses at a time.
For example, I would want to have the following expressions returned in seperate substrings so that one substring reads "5*4" and another seperate substring reads "(5*4) + 3"
I know I can use substring as follows:
String test = "test (542)";
test = test.substring(test.indexOf("(") + 1);
test = test.substring(0, test.indexOf(")"));
But how can I best approach handling multiple levels of parentheses of an unknown string.
Divide and Conquer would be a promising approach. You could define a recursive function, which will only need to handle a simple base case (like 5*4) explicitly. Whenever there are parentheses, call the function again with the text inside the parentheses.
You can do that with the Shunting-yard algorithm. If you only validate an expression, you do not need to implement all the algorithm. Your expression is valid when you have all the required operators and operands. In YouTube, you can see Shunting Yard Algorithm - Intro and Reverse Polish Notation.

Would ANTLR 4 allow me to create a parser for a boolean expression?

I have a program where users want to be able to filter out certain String criteria using the format
(someType != 'a' AND someType != 'b') OR (anotherType = 'abc' AND
somethingElse = 'cns')
We are looking into using ANTLR 4 for parsing this out. Each group will always be separated by an OR and each inner group will always be separated by ANDs.
I am a junior developer and I will learn ANTLR4 by reading the book if this is the route we want to go in. I just want to make sure ANTLR4 will take care of this.
We essentially want to know if the expression will evaluate to true or false based on this grammar.
Antlr doesn't evaluate expressions. It parses them.
"Evaluation" of the parsed result is up to you. Generally you attach node-building actions to grammar rules; with that, ANTLR will help you build a tree, and then you walk to the tree to evaluate it.
If you are really sneaky, you can likely do expression evaluation in the semantic actions. Passing values up is somewhat like passing created nodes up. Passing values down takes more effort, and I'm not the guy to describe how to do this with ANTLR.

expression evaluation with right-associativity in java

I am trying to solve a problem in which I have to solve a given expression consisting of one or more initialization in a same string with no operator precedence (although with bracketed sub-expressions). All the operators have right precedence so I have to evaluate it from right to left. I am confused how to proceed for the given problem. Detailed problem is given here : http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=108
I'll give you some ideas to try:
First off, you need to recursively evaluate inside brackets. You want to do brackets from most nested to least nested, so use a regex that matches brackets with no ) inside of them. Substring the result of the computation into the part of the string the bracketed expression took up.
If there are no brackets, then now you need to evaluate operators. The reason why the question requires right precedence is to force you to think about how to answer it - you can't just read the string and do calculations. You have to consider the whole string THEN start doing calculations, which means storing some structure describing it. There's a number of strategies you could use to do this, for example:
-You could tokenize the string, either using a scanner or regexes - continually try to see if the next item in the string is a number or which of the operators it is, and push what kind of token it is and its value onto a list. Then, you can evaluate the list from right to left using some kind of case/switch structure to determine what to do for each operator (either that, or each operator is associated with what it does to numbers). = itself would address a map of variable name keys to values, and insert the value under that variable's key, and then return (to be placed into the list) the value it produced, so it can be used for another assignment. It also seems like - can be determined as to whether it's subtraction or a negative number by whether there's a space on its right or not.
-Instead of tokenization, you could use regexes on the string as a whole. But tokenization is more robust. I tried to build a calculator based on applying regexes to the whole string over and over but it's so difficult to get all the rules right and I don't recommend it.
I've written an expression evaluating calculator like this before, so you can ask me questions if you run into specific problems.

Elegant way to do variable substitution in a java string

Pretty simple question and my brain is frozen today so I can't think of an elegant solution where I know one exists.
I have a formula which is passed to me in the form "A+B"
I also have a mapping of the formula variables to their "readable names".
Finally, I have a formula parser which will calculate the value of the formula, but only if its passed with the readable names for the variables.
For example, as an input I get
String formula = "A+B"
String readableA = "foovar1"
String readableB = "foovar2"
and I want my output to be "foovar1+foovar2"
The problem with a simple find and replace is that it can be easily be broken because we have no guarantees on what the 'readable' names are. Lets say I take my example again with different parameters
String formula = "A+B"
String readableA = "foovarBad1"
String readableB = "foovarAngry2"
If I do a simple find and replace in a loop, I'll end up replacing the capital A's and B's in the readable names I have already replaced.
This looks like an approximate solution but I don't have brackets around my variables
How to replace a set of tokens in a Java String?
That link you provided is an excellent source since matching using patterns is the way to go. The basic idea here is first get the tokens using a matcher. After this you will have Operators and Operands
Then, do the replacement individually on each Operand.
Finally, put them back together using the Operators.
A somewhat tedious solution would be to scan for all occurences of A and B and note their indexes in the string, and then use StringBuilder.replace(int start, int end, String str) method. (in naive form this would not be very efficient though, approaching smth like square complexity, or more precisely "number of variables" * "number of possible replacements")
If you know all of your operators, you could do split on them (like on "+") and then replace individual "A" and "B" (you'd have to do trimming whitespace chars first of course) in an array or ArrayList.
A simple way to do it is
String foumula = "A+B".replaceAll("\\bA\\b", readableA)
.replaceAll("\\bB\\b", readableB);
Your approach does not work fine that way
Formulas (mathematic Expressions) should be parsed into an expression structure (eg. expression tree).
Such that you have later Operand Nodes and Operator nodes.
Later this expression will be evaluated traversing the tree and considering the mathematical priority rules.
I recommend reading more on Expression parsing.
Matching Only
If you don't have to evaluate the expression after doing the substitution, you might be able to use a regex. Something like (\b\p{Alpha}\p{Alnum}*\b)
or the java string "(\\b\\p{Alpha}\\p{Alnum}*\\b)"
Then use find() over and over to find all the variables and store their locations.
Finally, go through the locations and build up a new string from the old one with the variable bits replaced.
Not that It will not do much checking that the supplied expression is reasonable. For example, it wouldn't mind at all if you gave it )A 2 B( and would just replace the A and B (like )XXX 2 XXX(). I don't know if that matters.
This is similar to the link you supplied in your question except you need a different regular expression than they used. You can go to http://www.regexplanet.com/advanced/java/index.html to play with regular expressions and figure out one that will work. I used it with the one I suggested and it finds what it needs in A+B and A + (C* D ) just fine.
Parsing
You parse the expression using one of the available parser generators (Antlr or Sable or ...) or find an algebraic expression parser available as open source and use it. (You would have to search the web to find those, I haven't used one but suspect they exist.)
Then you use the parser to generate a parsed form of the expression, replace the variables and reconstitute the string form with the new variables.
This one might work better but the amount of effort depends on whether you can find existing code to use.
It also depends on whether you need to validate the expression is valid according to the normal rules. This method will not accept invalid expressions, most likely.

Expression parsing using binary operators

I'm trying to figure out ways to parse an expression that uses all binary operators. Each operator is surrounded by exactly one set of parenthesis, such that:
5x^2 + 3x + 2
would be
((5*(x^2))+((3*x)+2))
and is taken as an args[] argument (more importantly, it is given as a String).
I'm recursively breaking this down, where each recursion breaks down the left part of the top binary operator and call the recursion with that expression as an argument, then again with the right. The base case is when the expression being passed contains no operators.
The problem I'm having is appropriately parsing the left side from the right side. I am trying to develop a way based upon a Scanner that counts the number of parenthesis counted overall, but can't seem to determine a final solution. Anyone have an idea how to parse this correctly in order to pass it as an expression to the recursive method.
P.s. - Language I am using is Java
EDIT::::
I am using this parser as a part of a GUI graph plotter, so I would set the variable (x) based on what value of the x-axis I am currently looking to generate on the GUI graph. So, the expression being parsed within the program (as shown in the second code tag above) would be broken down and operated on to produce a final "y" value that would correlate to the position on the window where a small dot would be used to represent that point on the line of the graph.
Maybe this will better explain how I am trying to use this.
I would start with an element class
interface Element {
}
And two elements
abstract class Operator implements Element {
Operand operate(Operand a, Operand b);
}
class Operand implements Element {
int value;
Operand(int value) { this.value = value; }
}
Now you can create your Operator factory
class OperatorFactory {
Operator createOperator(String symbol) {
if("+".equals(symbol))
return new Operator() {
Operator operate(Operand a, Operand b) {
return new Operand(a.value + b.value);
}
};
if("-".equals(symbol)) /* continued */
}
}
Now you're able to make yourself a stack processor that recurs when you reach a "(" and operates when you reach a ")". I imagine the rest will be pretty trivial from there.
What you want to implement is a simple recursive descent parser, which means that each production of your grammar will turn into a recursive function probably similar to what you're currently doing.
I don't know if you're familiar with the BNF syntax but here is one possible grammar for your language of binary operators. I'm omitting the power operator, which I leave for you to implement.
Expression ::= Expression + Term
Expression ::= Expression - Term
Expression ::= Term
Term ::= Term * Factor
Term ::= Term / Factor
Term ::= Factor
Factor ::= number
Factor ::= ( Expression )
With that you can see that you're defining an Expression by using an Expression, hence the use of recursive functions.
Please read this Wikipedia link and you'll immediately see how to implement what you want.
http://en.wikipedia.org/wiki/Recursive_descent_parser
Is your problem with logic or code?
In your logic, only issue I see is the precedence and associativity should also be considered (depending on the operator).
If the problem is with code, can you post the code? Also an example with teh expected output vs actual output would help so I don't have to put it in eclipse and run it myself.

Categories