aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Kummerländer2013-10-19 14:49:03 +0200
committerAdrian Kummerländer2013-10-19 14:49:03 +0200
commitaca18e1803b3d54e6c9d7444e8b9c1bf09d12f52 (patch)
treeebfde8ea3f2a7670a0fbc62fe81aac2c7662fc86
parent041a56a919ae49db46fa34adc8de90f0feb69bb0 (diff)
downloadSimpleParser-aca18e1803b3d54e6c9d7444e8b9c1bf09d12f52.tar
SimpleParser-aca18e1803b3d54e6c9d7444e8b9c1bf09d12f52.tar.gz
SimpleParser-aca18e1803b3d54e6c9d7444e8b9c1bf09d12f52.tar.bz2
SimpleParser-aca18e1803b3d54e6c9d7444e8b9c1bf09d12f52.tar.lz
SimpleParser-aca18e1803b3d54e6c9d7444e8b9c1bf09d12f52.tar.xz
SimpleParser-aca18e1803b3d54e6c9d7444e8b9c1bf09d12f52.tar.zst
SimpleParser-aca18e1803b3d54e6c9d7444e8b9c1bf09d12f52.zip
Fixed undefined behavior of tree construction
* Invalid input syntax led to undefined behavior when accessing the top element of an empty stack ** Fixed by introducing a new "topNodeFrom" function which throws an exeption in the case that the given std::stack reference is empty
-rw-r--r--src/parser.h2
-rw-r--r--src/tree.cc24
2 files changed, 17 insertions, 9 deletions
diff --git a/src/parser.h b/src/parser.h
index 54e540a..89c0493 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -6,7 +6,7 @@
namespace SimpleParser {
double calculate(std::string);
-std::string exportTree(std::string);
+std::string print(std::string);
}
diff --git a/src/tree.cc b/src/tree.cc
index 45484c6..1dcfca6 100644
--- a/src/tree.cc
+++ b/src/tree.cc
@@ -96,6 +96,14 @@ Node* Tree::addOperator(Node** place, char oper) {
return this->node_collection_.back().get();
}
+Node* topNodeFrom(const std::stack<Node*>& stack) {
+ if ( !stack.empty() ) {
+ return stack.top();
+ } else {
+ throw operator_exception();
+ }
+}
+
Node* Tree::buildTree(std::string term) {
std::stack<Node*> operandStack;
std::stack<Node*> operatorStack;
@@ -114,7 +122,7 @@ Node* Tree::buildTree(std::string term) {
if ( priority != -1 && (*termIter).size() == 1 ) {
if ( !operatorStack.empty() ) {
OperatorNode* lastNode(
- static_cast<OperatorNode*>(operatorStack.top())
+ static_cast<OperatorNode*>(topNodeFrom(operatorStack))
);
if ( getPriority(lastNode->getFunction()) < priority ) {
@@ -122,13 +130,13 @@ Node* Tree::buildTree(std::string term) {
this->addOperator(nullptr, currTerm[0])
);
} else {
- Node* currOperator = operatorStack.top();
+ Node* currOperator = topNodeFrom(operatorStack);
operatorStack.pop();
- currOperator->rightChild = operandStack.top();
+ currOperator->rightChild = topNodeFrom(operandStack);
operandStack.pop();
- currOperator->leftChild = operandStack.top();
+ currOperator->leftChild = topNodeFrom(operandStack);
operandStack.pop();
operandStack.push(currOperator);
@@ -161,20 +169,20 @@ Node* Tree::buildTree(std::string term) {
while ( !operatorStack.empty() ) {
OperatorNode *currOperator(
- static_cast<OperatorNode*>(operatorStack.top())
+ static_cast<OperatorNode*>(topNodeFrom(operatorStack))
);
operatorStack.pop();
- currOperator->rightChild = operandStack.top();
+ currOperator->rightChild = topNodeFrom(operandStack);
operandStack.pop();
- currOperator->leftChild = operandStack.top();
+ currOperator->leftChild = topNodeFrom(operandStack);
operandStack.pop();
operandStack.push(currOperator);
}
- return operandStack.top();
+ return topNodeFrom(operandStack);
}
}