Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I am currently trying to build a very simple compiler. I have created a function that converts a mathematical equation in infix notation to RPN using the shunting-yard algorithm however I have encountered a problem. I did not include error checking in my conversion function so I was wondering if there was a simple way to check if a function in infix notation is in correct infix notation syntax. This would enable me to keep my current conversion function without obscuring it with error checking.
If your expressions only consist of parentheses, values (constants and/or identifiers), and prefix, postfix and infix operators, then there are two error conditions you need to check:
The parentheses must match. It's hard not to notice this with the shunting yard algorithm, because there is a point in the algorithm where an open parenthesis is popped off the stack when a close parenthesis is encountered in the input. If you overpop the stack or you don't pop the entire stack at end of input, then the parentheses didn't balance.
The tokens must conform to the following simple regular expression:
PRE* VAL POST* ( INFIX PRE* VAL POST* )*
where
PRE is a prefix operator or an (
POST is a postfix operator or a )
VAL is a value: a constant or an identifier
That actually reduces to a two-state state machine: the initial state (state 0) could be called "expecting value" and the other state (state 1) could be called "expecting operator". Only state 1 is accepting, and the transitions are as follows:
State 0:
PRE → State 0
VAL → State 1
State 1:
POST → State 1
INFIX → State 0
All other transitions are to an error.
It's often necessary to implement this state machine in order to properly deal with unary minus (and other operators which could be prefix or infix), and it is, in any event, very simple to integrate into your input handling.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
Recently I have started looking into C++ from the basics and got to know (to my surprise) that I can give series of expressions in a single line separated by commas in some cases as below
//it'll execute all the expressions mentioned after condition seperated by comma
for(int i=0;condition;++i,++x,cout<<"in for loop"<<endl,z = z*2);
(x>y)? ++z,z1 = z*2, cout<<"printing statement"<<endl:cout<<"condition failed"<<endl,z = z/2;
Here, I have a confusion after this is working. Is it safe to code in that way or is there any problem coding in such a way?
Please clarify!!!
Correct me if i'm wrong anywhere, I'm just curious to know why most of the programmers don't use this way (I haven't seen such kind of lines anywhere)
The comma operator , evaluates each of its operands in sequence. In standardese, there is a sequence point between the evaluation of the left operand and the right operand.
In a expression which contains a comma operator, the value of the left operand is discarded and the expression takes on the value of the right operand. In both of the examples above, the comma operator is used in a void context, so none of the values are used.
So a statement like this where the value of the comma operator is not used:
exp1, exp2, exp3, exp4;
Is equivalent to the following sequence of statements:
exp1; exp2; exp3; exp4;
The first example is equivalent to the following:
for(int i=0;condition;) {
++i;
++x;
cout<<"in for loop"<<endl;
z = z*2;
}
And the second example:
if (x>y) {
++z;
z1 = z*2;
cout<<"printing statement"<<endl;
} else {
cout<<"condition failed"<<endl;
z = z/2;
}
Note that this is considerably more readable that the one-line versions. It's also easier to debug. Since debuggers typically step through code a line at a time, it breaks up the flow and is more granular.
Not indenting and spacing your code is not less costly regarding performance. It is unreadable, confusing and a pain to understand for you and for anyone who'd have to work with it.
Lot of people will prefer a well-syntaxed, beautifully and efficiently-indented code than a top-performance one. You can modify, debug and refract a code which might not work but has the advantage to be understandable.
On the other hand, very few codes remain unchanged and stay unread. There will always be a time when someone, may be you, will have to read it again and if it looks like the one if your OP, it will be very time costly to do.
It is allowed. In my opinion and i say without a reference that in general other programmers do not find your 'for' loop very readable. Sometimes in a for loop you want to do other things then just for (int i = 0; i < 10; ++i){"do something"}For example increment 'i' in every loop with two. Reading code should be like reading a text. If you are reading a book you do not want it to be unnecessary difficult.
Your other question was about the safety of the statement. The biggest problem with the code is that you might get confused about what you are doing exactly. Bugs are caused by human errors (computers are deterministic and are executing machine code which ultimately has been written by a human) and the question about safety mainly depends on how you define it.
To give you some tips. When i just started programming C++ i looked a lot on CPP reference. I will give you a link where you can read about the syntax and what is allowed/possible. On this website there are quite a lot of examples on all kinds of statements. They will in general not put 5 or 6 operations within in a single line. If there are more variables that you want to change then you might want to do that in the scope of the for loop so it will be more readable instead of inside the for loop.
http://en.cppreference.com/w/cpp/language/for
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I am now in the midst of making a simple bytecode interpreter that uses RPN for expression notation and really postfix notation for anything, but now I've come to the question which is: can short circuit evaluation actually be used on postfix expressions? For example when evaluating the expression (false && (factorial(7) > factorial(5))) C++ knows the result of the && operator on the two operands evaluates to false before it even gets to the second operand, since (false && anything) is always equal to false. Now when you put this in RPN, you get (false (7 factorial 5 factorial >) &&).
I wanted to build an efficient RPN expression parser, so the problem is this: how do I make an efficient RPN expression parser with short circuit evaluation?
You would evaluate an RPN expression in two phases.
Phase 1: parse the RPN, and construct a tree representation of the RPN. So, in this tree, for example, the && node has two children nodes, for each half of the expression. Constructing this tree is a nearly identical process as evaluating the RPN, except for the evaluating part, which gets replaced by the operation of constructing a new node, and linking its child nodes to their new parent node, then pushing the parent node back on the RPN evaluation stack.
Phase 2: evaluate the constructed tree, using recursive descent. At this point, short-circuit evaluation becomes trivial: evaluate the left-hand child of a &&, then decide whether you actually want to evaluate the right-hand child.
Ditto for the || node, etc...
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
The error message appears on Xcode that says "invalid operands to binary expression.
in my code I'm using an array of a struct, i'm trying to sort input data in an ascending order, and i'm getting this error message at the "if" condition shown in the print screen at this link:
https://www.dropbox.com/s/0mch2gbxcif0a20/Screen%20Shot%202016-04-27%20at%2012.45.45%20PM.png?dl=0
The Code
if (studentsInfo[i] > studentsInfo[i + 1]) {}
The Error
Invalid operands to binary expression ('students' and 'students')
What do you compare in your program? As I see, you have to compare names, but all you do is compare an array element which is a struct data type.
If you are trying to compare names, you have to use dot "." operator to reach names. After yo compare names, you can change the elements's place.
The error means that > only takes two arguments and you are using it for something else. In this case you are comparing an entire data structure that does not have an override for > operator and is an undefined behavior. StudentsInfo[i] is a data structure that has more than one element in it. Replace the StudentsInfo[i] with StudentsInfo[i].GPA or another element whose data type has a defined > operator.
This question already has answers here:
Building a math expression evaluator
(2 answers)
Closed 7 years ago.
I'm implementing a calculator in C ++ that respects the priorities of parentheses. I am trying to use std :: string :: find_last_of to find the last occurrence of ( and std :: string :: find to find the first occurrence of ). Once that is done, I reckon the content of the extracted substring and continuing with the rest of the string.
For example:
1 + 1 * (9 * (11-1 + 2))
I find the last occurrence of (, the first of ) and calculating 11-1 + 2. And so it continues.
Is this the right approach to this problem or is there something better?
Thank you.
You can use Reversed Polish Notation:
You will need to convert the expression into reversed polish notation and then implement a stack based algorithm to pop and push to the final answer.
Have a look at the Shunting- Yard algorithm here: To convert the expression into RPN.
https://en.wikipedia.org/wiki/Shunting-yard_algorithm
Also Have a look at
Writing a simple equation parser
For help to implement the stack, have a look here:
C++ Calculator using Stacks and Queues
One of the standard approaches to this problem consists of 2 steps:
1) Convert your expression to Reverse Polish notation: https://en.wikipedia.org/wiki/Reverse_Polish_notation using Shunting-yard algorithm https://en.wikipedia.org/wiki/Shunting-yard_algorithm
2) Evaluate converted expression using stack.
The another way to do this:
1) Easy step: Write Backus–Naur Form of your expressions https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form
And after you have 2 options:
2a) Build Finite-State Machine: https://en.wikipedia.org/wiki/Finite-state_machine (exists a lot of tools to do this: ANTLR, ...).
2b) Recursive descent method: https://en.wikipedia.org/wiki/Recursive_descent_parser
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I'm getting the error 'term does not evaluate to a function taking 1 arguments' on the following line in my code:
steerToSpiralRefPoint(m_CentrePos);
But I'm not sure why this is... Is it that the function will only take 1 argument as a parameter, but since the 'm_centrePos' variable holds more than 1 attribute, the function is effectively receiving several parameters?
I have defined 'steerToSpiralRefPoint' with the line:
CDirectOverflyItem steerToSpiralRefPoint = new CDirectOverflyItem::SteerStep(const CHeloData aHeloData);
'm_CentrePos' has been assigned the value 'cCentrePos' at the start of this file ('cCentrePos' is a variable of type 'CCoordinate', which has a number of attributes- latitude, longitude, altitude, etc).
'CDirectOverflyItem's also has a number of attributes- ground speed, wind speed, wind angle, etc.
Can anyone point out to me why I'm getting this error, and how I should correct it?
This expression
steerToSpiralRefPoint(m_CentrePos);
is a postfix expression of a function call. However as it follows from your post steerToSpiralRefPoint is not a function (or function pointer) but a pointer to an object. If you want to assign a value to the pointer then you have to write
steerToSpiralRefPoint = m_CentrePos;
Or if there is an operator function for this type then the code should look as
( *steerToSpiralRefPoint )( m_CentrePos );
And this construction
CDirectOverflyItem steerToSpiralRefPoint = new CDirectOverflyItem::SteerStep(const CHeloData );
is also invalid. You may not use qualifiers before variables in expressions. They may be used only in declarations.
It seems that the issue was that I was trying to pass the wrong data type into the parameter- it was expecting a 'CHeloData', but I was trying to give it a 'CCoordinate'.