Files
fsh-oop/include/ast/ast_base.hpp
2025-08-29 00:02:45 +02:00

96 lines
2.4 KiB
C++

#pragma once
#include <memory>
#include <sstream>
#include <stdexcept>
#include <string>
#include "lexer.hpp"
#include "util/text.hpp"
#include "util/error.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<AstNode>;
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 <class T>
static std::shared_ptr<T> Optional(std::list<Token>::iterator& it, std::shared_ptr<T>& node_ptr);
template <class T>
static std::shared_ptr<T> Optional(std::list<Token>::iterator& it) {
std::shared_ptr<T> node_ptr;
return Optional<T>(it, node_ptr);
}
// Pravi od narednih tokena zadati Node ako ne uspe izbaci AstBuildError
template <class T>
static std::shared_ptr<T> Mandatory(std::list<Token>::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 util::LazyError {
public:
AstBuildError() {}
};
class AstUnexpectedTypeError : public AstBuildError {
public:
AstUnexpectedTypeError(Lexer::TokenType type) : type(type){};
private:
Lexer::TokenType type;
std::string build_msg() const noexcept override {
return (std::string) "Unexpected " + util::tokens[type];
};
};
class AstNoRedirectError : public AstBuildError {
private:
std::string build_msg() const noexcept override {
return "No redirects provided";
};
};
}