#include "parser.h" #include "expression.h" #include #include #include #include #include using namespace std; using namespace boost; /////////////////////////////////////////////////////////////////////////////// // Parser /////////////////////////////////////////////////////////////////////////////// Parser::Parser() { } Parser::Parser(const Parser& p) { } Parser& Parser::operator=(const Parser& p) { } Parser::~Parser() { } Parser* Parser::get_parser() { static Parser parser; return &parser; } ExpressionPtr Parser::parse(Tokenizer& tok) const { return get_add_expression(tok); } ExpressionPtr Parser::get_add_expression(Tokenizer& tok) const { ExpressionPtr first = get_mult_expression(tok); ExpressionVector v; while (true) { if (tok == Tokenizer()) { break; } string curr = *tok; try { Operator op = to_operator(curr); if (op == MULTIPLY || op == DIVIDE) { throw BadOperatorSymbol(); } ++tok; ExpressionPtr val = get_mult_expression(tok); v.push_back(make_pair(val, op)); } catch (const BadOperatorSymbol& e) { throw BadInput("Operator expected, found " + curr); } } if (v.size() == 0) { return first; } else { return ExpressionPtr(new AddExpression(first, v)); } } ExpressionPtr Parser::get_mult_expression(Tokenizer& tok) const { ExpressionPtr first = get_integer_or_bracket(tok); ExpressionVector v; while (true) { if (tok == Tokenizer()) { break; } string curr = *tok; try { Operator op = to_operator(curr); if (op == PLUS || op == MINUS) { break; } ++tok; ExpressionPtr val = get_integer_or_bracket(tok); v.push_back(make_pair(val, op)); } catch (const BadOperatorSymbol& e) { break; } } if (v.size() == 0) { return first; } else { return ExpressionPtr(new MultExpression(first, v)); } } ExpressionPtr Parser::get_integer_or_bracket(Tokenizer& tok) const { if (tok == Tokenizer()) { throw BadInput("Integer or bracket expected, found end of input"); } else { string curr = *tok; if (is_numeric(curr)) { ++tok; return ExpressionPtr(new IntegerExpression(atoi(curr.c_str()))); } else if (curr == "(") { ++tok; ExpressionPtr e = get_add_expression(tok); if (tok == Tokenizer()) { throw BadInput(") expected, found end of input"); } curr = *tok; if (curr == ")") { ++tok; return e; } else { throw BadInput(") expected, found " + curr); } } else { throw BadInput("Integer or bracket expected, found " + curr); } } } bool Parser::is_numeric(const std::string& s) const { if (s.size() == 0) { return false; } else { string::const_iterator i = s.begin(); if (s.size() >= 2 && s[0] == '-') { ++i; } while (i != s.end()) { if (!isdigit(*i++)) { return false; } } return true; } } /////////////////////////////////////////////////////////////////////////////// // BadInput /////////////////////////////////////////////////////////////////////////////// Parser::BadInput::BadInput(const string& m) : msg(m) { } const string& Parser::BadInput::get_message() const { return msg; }