#pragma once #include #include #include #include #include "lexer.hpp" #include "util/text.hpp" namespace fsh { enum NodeType { COMMAND_LINE, COMMAND, PIPELINE_COMMAND, LREDIRECTS, RREDIRECTS, REDIRECTS, STRING_LITERAL, COMMAND_ARGUMENT, TOKEN }; class AstNode { friend class std::shared_ptr; public: NodeType gtype() { return type; } const std::string& gname() { return name; }; protected: using TokenType = Lexer::TokenType; AstNode(NodeType type, std::string name) : type(type), name(name) {} // Pokusa da napravi od narednih tokena zadati Node ako ne uspe vrati null template static std::shared_ptr Optional(std::list::iterator& it, std::shared_ptr& node_ptr); template static std::shared_ptr Optional(std::list::iterator& it) { std::shared_ptr node_ptr; return Optional(it, node_ptr); } // Pravi od narednih tokena zadati Node ako ne uspe izbaci AstBuildError template static std::shared_ptr Mandatory(std::list::iterator& it) { return T::build(it); } private: AstNode(); AstNode(const AstNode&); NodeType type; const std::string name; }; class ExecutableNode : public AstNode { public: virtual void print(int indent) {}; virtual void execute(std::istream& in, std::ostream& out) {} protected: ExecutableNode(NodeType type, std::string Name) : AstNode(type, Name) {} private: }; class AstBuildError : public std::runtime_error { public: AstBuildError(std::string err) : std::runtime_error(err) {} }; }