#pragma once #include "lexer.h" #include "exception.h" #include #include namespace usql { enum class ColumnType { integer_type, float_type, varchar_type }; enum class NodeType { true_node, null_value, int_value, float_value, string_value, database_value, logical_operator, relational_operator, arithmetical_operator, create_table, create_table_as_select, insert_into, select_from, delete_from, update_table, load_table, save_table, drop_table, column_name, column_value, function, column_def, error }; struct Node { NodeType node_type; Node(const NodeType type) : node_type(type) {} }; struct ColNameNode : Node { std::string name; ColNameNode(const std::string col_name) : Node(NodeType::column_name), name(col_name) {} }; struct SelectColNode : Node { std::unique_ptr value; std::string name; SelectColNode(std::unique_ptr column, const std::string& alias) : Node(NodeType::column_name), value(std::move(column)), name(alias) {} }; struct ColDefNode : Node { std::string name; ColumnType type; int order; int length; bool null; ColDefNode(const std::string col_name, ColumnType col_type, int col_order, int col_len, bool nullable) : Node(NodeType::column_def), name(col_name), type(col_type), order(col_order), length(col_len), null(nullable) {} }; struct FunctionNode : Node { std::string function; std::vector> params; FunctionNode(const std::string func_name, std::vector> pars) : Node(NodeType::function), function(func_name), params(std::move(pars)) {} }; struct TrueNode : Node { TrueNode() : Node(NodeType::true_node) {} }; struct ValueNode : Node { ValueNode(NodeType type) : Node(type) {} virtual bool isNull() { return false; } virtual long getIntValue() = 0; virtual double getDoubleValue() = 0; virtual std::string getStringValue() = 0; virtual ~ValueNode() {}; }; struct NullValueNode : ValueNode { NullValueNode() : ValueNode(NodeType::null_value) {} bool isNull() override { return true; } long getIntValue() override { throw Exception("not supported on null value"); }; double getDoubleValue() override { throw Exception("not supported on null value"); }; std::string getStringValue() override { throw Exception("not supported on null value"); }; }; struct IntValueNode : ValueNode { long value; IntValueNode(long value) : ValueNode(NodeType::int_value), value(value) {} long getIntValue() override { return value; }; double getDoubleValue() override { return (double) value; }; std::string getStringValue() override { return std::to_string(value); } }; struct DoubleValueNode : ValueNode { double value; DoubleValueNode(double value) : ValueNode(NodeType::float_value), value(value) {} long getIntValue() override { return (long) value; }; double getDoubleValue() override { return value; }; std::string getStringValue() override { return std::to_string(value); } }; struct StringValueNode : ValueNode { std::string value; StringValueNode(std::string value) : ValueNode(NodeType::string_value), value(value) {} long getIntValue() override { return std::stoi(value); }; double getDoubleValue() override { return std::stod(value); }; std::string getStringValue() override { return value; }; }; struct DatabaseValueNode : Node { std::string col_name; DatabaseValueNode(std::string name) : Node(NodeType::database_value), col_name(name) {} }; enum class LogicalOperatorType { and_operator, or_operator, not_operator }; struct LogicalOperatorNode : Node { LogicalOperatorType op; std::unique_ptr left; std::unique_ptr right; LogicalOperatorNode(LogicalOperatorType op, std::unique_ptr left, std::unique_ptr right) : Node(NodeType::logical_operator), op(op), left(std::move(left)), right(std::move(right)) {}; }; enum class RelationalOperatorType { equal, greater, greater_equal, lesser, lesser_equal, not_equal // like }; struct RelationalOperatorNode : Node { RelationalOperatorType op; std::unique_ptr left; std::unique_ptr right; RelationalOperatorNode(RelationalOperatorType op, std::unique_ptr left, std::unique_ptr right) : Node(NodeType::relational_operator), op(op), left(std::move(left)), right(std::move(right)) {}; }; enum class ArithmeticalOperatorType { copy_value, // just copy lef value and do nothing with it plus_operator, minus_operator, multiply_operator, divide_operator }; struct ArithmeticalOperatorNode : Node { ArithmeticalOperatorType op; std::unique_ptr left; std::unique_ptr right; ArithmeticalOperatorNode(ArithmeticalOperatorType op, std::unique_ptr left, std::unique_ptr right) : Node(NodeType::arithmetical_operator), op(op), left(std::move(left)), right(std::move(right)) {}; }; struct CreateTableNode : Node { std::string table_name; std::vector cols_defs; CreateTableNode(const std::string& name, std::vector defs) : Node(NodeType::create_table), table_name(name), cols_defs(defs) {} }; struct InsertIntoTableNode : Node { std::string table_name; std::vector cols_names; std::vector> cols_values; InsertIntoTableNode(const std::string name, std::vector names, std::vector> values) : Node(NodeType::insert_into), table_name(name), cols_names(names), cols_values(std::move(values)) {} }; struct SelectFromTableNode : Node { std::string table_name; std::unique_ptr> cols_names; std::unique_ptr where; SelectFromTableNode(std::string name, std::unique_ptr> names, std::unique_ptr where_clause) : Node(NodeType::select_from), table_name(name), cols_names(std::move(names)), where(std::move(where_clause)) {} }; struct CreateTableAsSelectNode : Node { std::string table_name; std::unique_ptr select_table; CreateTableAsSelectNode(const std::string name, std::unique_ptr table) : Node(NodeType::create_table_as_select), table_name(name), select_table(std::move(table)) {} }; struct UpdateTableNode : Node { std::string table_name; std::vector cols_names; std::vector> values; std::unique_ptr where; UpdateTableNode(std::string name, std::vector names, std::vector> vals, std::unique_ptr where_clause) : Node(NodeType::update_table), table_name(name), cols_names(names), values(std::move(vals)), where(std::move(where_clause)) {} }; struct LoadIntoTableNode : Node { std::string table_name; std::string filename; LoadIntoTableNode(const std::string name, std::string file) : Node(NodeType::load_table), table_name(name), filename(file) {} }; struct SaveTableNode : Node { std::string table_name; std::string filename; SaveTableNode(const std::string& name, std::string file) : Node(NodeType::save_table), table_name(name), filename(file) {} }; struct DropTableNode : Node { std::string table_name; DropTableNode(const std::string& name) : Node(NodeType::drop_table), table_name(name) {} }; struct DeleteFromTableNode : Node { std::string table_name; std::unique_ptr where; DeleteFromTableNode(const std::string& name, std::unique_ptr where_clause) : Node(NodeType::delete_from), table_name(name), where(std::move(where_clause)) {} }; class Parser { private: public: Parser(); std::unique_ptr parse(const std::string &code); private: std::unique_ptr parse_create_table(); std::unique_ptr parse_load_table(); std::unique_ptr parse_save_table(); std::unique_ptr parse_drop_table(); std::unique_ptr parse_insert_into_table(); std::unique_ptr parse_select_from_table(); std::unique_ptr parse_delete_from_table(); std::unique_ptr parse_update_table(); std::unique_ptr parse_where_clause(); std::unique_ptr parse_operand_node(); std::unique_ptr parse_value(); RelationalOperatorType parse_relational_operator(); LogicalOperatorType parse_logical_operator(); ArithmeticalOperatorType parse_arithmetical_operator(); private: Lexer m_lexer; std::unique_ptr parse_relational_expression(); }; }