aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nodes.cc3
-rw-r--r--src/nodes.h1
-rw-r--r--src/tree.cc48
-rw-r--r--src/tree.h1
-rw-r--r--src/utils.cc75
5 files changed, 90 insertions, 38 deletions
diff --git a/src/nodes.cc b/src/nodes.cc
index 390eac7..fac74a0 100644
--- a/src/nodes.cc
+++ b/src/nodes.cc
@@ -10,6 +10,9 @@ namespace SimpleParser {
OperandNode::OperandNode(double val):
value_(val) { }
+OperandNode::OperandNode(std::string identifier):
+ value_(42) { }
+
double OperandNode::solve() {
return this->value_;
}
diff --git a/src/nodes.h b/src/nodes.h
index 3a99474..a59f4a5 100644
--- a/src/nodes.h
+++ b/src/nodes.h
@@ -39,6 +39,7 @@ class OperatorNode: public Node {
class OperandNode: public Node {
public:
explicit OperandNode(double);
+ explicit OperandNode(std::string);
virtual double solve();
virtual NodeType getType();
diff --git a/src/tree.cc b/src/tree.cc
index 0f5c2d8..2dfb786 100644
--- a/src/tree.cc
+++ b/src/tree.cc
@@ -84,6 +84,18 @@ Node* Tree::addOperand(Node** place, double value) {
return this->node_collection_.back().get();
}
+Node* Tree::addOperand(Node** place, std::string value) {
+ this->node_collection_.emplace_back(
+ new OperandNode(value)
+ );
+
+ if ( place != nullptr ) {
+ *place = this->node_collection_.back().get();
+ }
+
+ return this->node_collection_.back().get();
+}
+
Node* Tree::addOperator(Node** place, char oper) {
this->node_collection_.emplace_back(
new OperatorNode(oper)
@@ -117,7 +129,9 @@ Node* Tree::buildTree(std::string term) {
const std::string& currTerm = (*termIter);
const TokenType token = getTokenType(currTerm[0]);
- if ( token != TokenType::VALUE_NUMBER && (*termIter).size() == 1 ) {
+ if ( token != TokenType::VALUE_NUMBER &&
+ token != TokenType::VALUE_IDENTIFIER &&
+ (*termIter).size() == 1 ) {
if ( !operatorStack.empty() ) {
OperatorNode* lastNode(
static_cast<OperatorNode*>(topNodeFrom(operatorStack))
@@ -150,14 +164,30 @@ Node* Tree::buildTree(std::string term) {
tmpLexer = lexer(*termIter);
if ( tmpLexer.size() == 1 ) {
- double value;
- std::istringstream convertStream(tmpLexer[0]);
- convertStream >> value;
-
- operandStack.push(
- this->addOperand(nullptr,value)
- );
- } else if ( tmpLexer.size() > 1 ) {
+ switch ( getTokenType(tmpLexer[0][0]) ) {
+ case TokenType::VALUE_NUMBER: {
+ double value;
+ std::istringstream convertStream(tmpLexer[0]);
+ convertStream >> value;
+
+ operandStack.push(
+ this->addOperand(nullptr,value)
+ );
+
+ break;
+ }
+ case TokenType::VALUE_IDENTIFIER: {
+ operandStack.push(
+ this->addOperand(nullptr,tmpLexer[0])
+ );
+
+ break;
+ }
+ default: {
+ throw operator_exception();
+ }
+ }
+ } else {
operandStack.push(
buildTree(*termIter)
);
diff --git a/src/tree.h b/src/tree.h
index 5beec87..f20f765 100644
--- a/src/tree.h
+++ b/src/tree.h
@@ -18,6 +18,7 @@ class Tree {
private:
Node* addOperand(Node**, double);
+ Node* addOperand(Node**, std::string);
Node* addOperator(Node**, char);
Node* buildTree(std::string);
diff --git a/src/utils.cc b/src/utils.cc
index 112bc20..4e2ed91 100644
--- a/src/utils.cc
+++ b/src/utils.cc
@@ -1,36 +1,42 @@
#include "utils.h"
+#include "tree.h"
#include "exceptions.h"
-#include "tree.h"
+#include <cctype>
namespace SimpleParser {
TokenType getTokenType(char tmp) {
- switch ( tmp ) {
- case '-':
- return TokenType::OPERATOR_PLUS;
- case '+':
- return TokenType::OPERATOR_MINUS;
- case '/':
- return TokenType::OPERATOR_DIVIDE;
- case '*':
- return TokenType::OPERATOR_MULTIPLY;
- case '^':
- return TokenType::OPERATOR_POWER;
- case '(':
- return TokenType::PARENTHESES_OPEN;
- case ')':
- return TokenType::PARENTHESES_CLOSE;
- case ',':
- return TokenType::VALUE_NUMBER;
- default:
- return TokenType::VALUE_NUMBER;
+ if ( std::isalpha(tmp) ) {
+ return TokenType::VALUE_IDENTIFIER;
+ } else {
+ switch ( tmp ) {
+ case '-':
+ return TokenType::OPERATOR_PLUS;
+ case '+':
+ return TokenType::OPERATOR_MINUS;
+ case '/':
+ return TokenType::OPERATOR_DIVIDE;
+ case '*':
+ return TokenType::OPERATOR_MULTIPLY;
+ case '^':
+ return TokenType::OPERATOR_POWER;
+ case '(':
+ return TokenType::PARENTHESES_OPEN;
+ case ')':
+ return TokenType::PARENTHESES_CLOSE;
+ case ',':
+ return TokenType::VALUE_NUMBER;
+ default:
+ return TokenType::VALUE_NUMBER;
+ }
}
}
std::vector<std::string> lexer(std::string term) {
std::string tmp;
- std::string tmpNum;
+ std::string tmpNumber;
+ std::string tmpIdentifier;
std::vector<std::string> output;
TokenType token;
TokenType lastToken;
@@ -42,19 +48,28 @@ std::vector<std::string> lexer(std::string term) {
termIter++ ) {
token = getTokenType(*termIter);
- if ( token == TokenType::VALUE_NUMBER ||
- ( token == TokenType::OPERATOR_MINUS &&
+ if ( token == TokenType::VALUE_NUMBER ||
+ token == TokenType::VALUE_IDENTIFIER ||
+ ( token == TokenType::OPERATOR_MINUS &&
termIter == term.begin() ) ) {
if ( level > 0 ) {
tmp += *termIter;
} else {
- tmpNum += *termIter;
+ if ( token == TokenType::VALUE_NUMBER ) {
+ tmpNumber += *termIter;
+ } else if ( token == TokenType::VALUE_IDENTIFIER ) {
+ tmpIdentifier += *termIter;
+ }
}
} else {
- if ( lastToken == TokenType::VALUE_NUMBER &&
- level == 0 ) {
- output.push_back(tmpNum);
- tmpNum.clear();
+ if ( level == 0 ) {
+ if ( lastToken == TokenType::VALUE_NUMBER ) {
+ output.push_back(tmpNumber);
+ tmpNumber.clear();
+ } else if ( lastToken == TokenType::VALUE_IDENTIFIER ) {
+ output.push_back(tmpIdentifier);
+ tmpIdentifier.clear();
+ }
}
switch ( token ) {
@@ -98,7 +113,9 @@ std::vector<std::string> lexer(std::string term) {
}
if ( lastToken == TokenType::VALUE_NUMBER ) {
- output.push_back(tmpNum);
+ output.push_back(tmpNumber);
+ } else if ( lastToken == TokenType::VALUE_IDENTIFIER ) {
+ output.push_back(tmpIdentifier);
} else if ( lastToken != TokenType::PARENTHESES_CLOSE ) {
throw operator_exception();
}