Massive reformating and cleanup

This commit is contained in:
2024-12-06 21:07:54 +01:00
parent 79390b94b7
commit d2cbdc2910
33 changed files with 1030 additions and 1100 deletions

View File

@ -1,18 +1,18 @@
/*
* Fsh Grammar
*
* Command_Line ::= Command EOF
*
* Command_Line ::= Command EOF
* | Command Pipeline_Command
*
*
* Pipeline_Command ::= "|" Command EOF
* | "|" Command "|" Pipeline_Command
*
*
* Command ::= Command_Name [Flag_Opt] {Command_Argument} [Redirect]
*
*
* Redirects ::= [LRedirect Word] RRedirect Word | [RRedirect Word] LRedirect Word
*
*
* Command_Argument ::= Word | String_Literal
*
*
* Command_Name ::= Word
*/
#pragma once
@ -21,26 +21,24 @@
#include "util/text.hpp"
#include "ast/ast_base.hpp"
#include "ast/ast_token.hpp"
#include "ast/ast_component.hpp"
#include "ast/ast_executable.hpp"
#include "ast/ast_token.hpp"
namespace fsh {
class AstFactory {
public:
class AstFactory {
public:
// Generates an abstract syntax tree
static std::shared_ptr<ExecutableNode> generate_ast(std::list<Token>& list) {
auto it = list.begin();
return CommandLineNode::build(it);
}
// Generates an abstract syntax tree
static std::shared_ptr<ExecutableNode> generate_ast(std::list<Token>& list) {
auto it = list.begin();
return CommandLineNode::build(it);
}
private:
static AstFactory& get_factory();
AstFactory() {}
AstFactory(const AstFactory&) = default;
};
private:
static AstFactory& get_factory();
AstFactory() {}
AstFactory(const AstFactory&) = default;
};
}
} // namespace fsh

View File

@ -1,67 +1,73 @@
#pragma once
#include <string>
#include <memory>
#include <stdexcept>
#include <sstream>
#include <stdexcept>
#include <string>
#include "lexer.hpp"
#include "util/text.hpp"
namespace fsh {
enum NodeType {
COMMAND_LINE,
COMMAND,
PIPELINE_COMMAND,
LREDIRECTS,
RREDIRECTS,
REDIRECTS,
STRING_LITERAL,
COMMAND_ARGUMENT,
TOKEN
};
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;};
class AstNode {
friend class std::shared_ptr<AstNode>;
protected:
using TokenType = Lexer::TokenType;
AstNode(NodeType type, std::string name) : type(type), name(name) {}
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) {}
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);
}
template <class T>
static std::shared_ptr<T> Mandatory(std::list<Token>::iterator& it) {return T::build(it);}
template <class T>
static std::shared_ptr<T> Optional(std::list<Token>::iterator& it, std::shared_ptr<T>& node_ptr);
private:
AstNode();
AstNode(const AstNode&);
NodeType type;
const std::string name;
};
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);
}
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:
};
template <class T>
static std::shared_ptr<T> Mandatory(std::list<Token>::iterator& it) {
return T::build(it);
}
class AstBuildError : public std::runtime_error {
public:
AstBuildError(std::string err) : std::runtime_error(err) {}
};
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) {}
};
} // namespace fsh

View File

@ -11,80 +11,73 @@
namespace fsh {
class CommandArgumentNode : public AstNode {
public:
static std::shared_ptr<CommandArgumentNode> build(std::list<Token>::iterator& it);
class CommandArgumentNode : public AstNode {
public:
static std::shared_ptr<CommandArgumentNode> build(std::list<Token>::iterator& it);
Lexer::TokenType gtoken_type() {return type;}
std::string& gvalue() {return value;}
Lexer::TokenType gtoken_type() { return type; }
std::string& gvalue() { return value; }
protected:
CommandArgumentNode(TokenNode<TokenType::WORD>::shared word)
: AstNode(NodeType::COMMAND_ARGUMENT, "StringArgument"),
type(word->gtoken_type()),
value(word->gvalue()) {}
CommandArgumentNode(TokenNode<TokenType::STRING_LITERAL>::shared word)
: AstNode(NodeType::COMMAND_ARGUMENT, "StringArgument"),
type(word->gtoken_type()),
value(word->gvalue()) {}
protected:
CommandArgumentNode(TokenNode<TokenType::WORD>::shared word) :
AstNode(NodeType::COMMAND_ARGUMENT, "StringArgument"), type(word->gtoken_type()), value(word->gvalue()) {}
private:
Lexer::TokenType type;
std::string value;
};
CommandArgumentNode(TokenNode<TokenType::STRING_LITERAL>::shared word) :
AstNode(NodeType::COMMAND_ARGUMENT, "StringArgument"), type(word->gtoken_type()), value(word->gvalue()) {}
class LRedirectNode : public AstNode {
public:
static std::shared_ptr<LRedirectNode> build(std::list<Token>::iterator& it);
private:
Lexer::TokenType type;
std::string value;
};
std::string gvalue() {return input;}
class LRedirectNode : public AstNode {
public:
static std::shared_ptr<LRedirectNode> build(std::list<Token>::iterator& it);
protected:
LRedirectNode(TokenNode<TokenType::LREDIRECTION>::shared, TokenNode<TokenType::WORD>::shared in)
: AstNode(NodeType::LREDIRECTS, "LRedirectNode"),
input(in->gvalue()) {}
std::string gvalue() { return input; }
private:
std::string input;
};
protected:
LRedirectNode(TokenNode<TokenType::LREDIRECTION>::shared, TokenNode<TokenType::WORD>::shared in) :
AstNode(NodeType::LREDIRECTS, "LRedirectNode"), input(in->gvalue()) {}
private:
std::string input;
};
class RRedirectNode : public AstNode {
public:
static std::shared_ptr<RRedirectNode> build(std::list<Token>::iterator& it);
class RRedirectNode : public AstNode {
public:
static std::shared_ptr<RRedirectNode> build(std::list<Token>::iterator& it);
std::string gvalue() {return output;}
bool gappend() {return append;}
std::string gvalue() { return output; }
bool gappend() { return append; }
protected:
RRedirectNode(TokenNode<TokenType::RREDIRECTION>::shared rr, TokenNode<TokenType::WORD>::shared out)
: AstNode(NodeType::RREDIRECTS, "LRedirectNode"),
output(out->gvalue()),
append(rr->gvalue().size()>1) {}
protected:
RRedirectNode(TokenNode<TokenType::RREDIRECTION>::shared rr, TokenNode<TokenType::WORD>::shared out) :
AstNode(NodeType::RREDIRECTS, "LRedirectNode"), output(out->gvalue()), append(rr->gvalue().size() > 1) {}
private:
std::string output;
bool append;
};
private:
std::string output;
bool append;
};
class RedirectsNode : public AstNode {
public:
static std::shared_ptr<RedirectsNode> build(std::list<Token>::iterator& it);
class RedirectsNode : public AstNode {
public:
static std::shared_ptr<RedirectsNode> build(std::list<Token>::iterator& it);
std::optional<std::string> ginput() {return input;}
std::optional<std::string> goutput() {return output;}
bool gappend() {return append;}
std::optional<std::string> ginput() { return input; }
std::optional<std::string> goutput() { return output; }
bool gappend() { return append; }
protected:
RedirectsNode(std::shared_ptr<LRedirectNode> in, std::shared_ptr<RRedirectNode> out)
: AstNode(NodeType::REDIRECTS, "RedirectNode"),
input(util::mk_optional(in)),
output(util::mk_optional(out)) {if(out) append = out->gappend();}
protected:
RedirectsNode(std::shared_ptr<LRedirectNode> in, std::shared_ptr<RRedirectNode> out) :
AstNode(NodeType::REDIRECTS, "RedirectNode"), input(util::mk_optional(in)), output(util::mk_optional(out)) {
if (out) append = out->gappend();
}
private:
std::optional<std::string> input;
std::optional<std::string> output;
bool append = false;
};
private:
std::optional<std::string> input;
std::optional<std::string> output;
bool append = false;
};
}
} // namespace fsh

View File

@ -1,78 +1,69 @@
#pragma once
#include <memory>
#include <stdexcept>
#include <optional>
#include <stdexcept>
#include "ast/ast_base.hpp"
#include "ast/ast_token.hpp"
#include "ast/ast_component.hpp"
#include "ast/ast_token.hpp"
#include "lexer.hpp"
#include "util/text.hpp"
namespace fsh {
class CommandNode : public ExecutableNode {
using ArgumentVec = std::vector<std::shared_ptr<CommandArgumentNode> >;
public:
static std::shared_ptr<CommandNode> build(std::list<Token>::iterator& it);
virtual void print(int indent) override;
virtual void execute(std::istream &in, std::ostream &out) override;
class CommandNode : public ExecutableNode {
using ArgumentVec = std::vector<std::shared_ptr<CommandArgumentNode> >;
protected:
CommandNode(
TokenNode<TokenType::WORD>::shared cmd_name,
TokenNode<TokenType::FLAG>::shared flag,
ArgumentVec args,
std::shared_ptr<RedirectsNode> redirects
) : ExecutableNode(NodeType::COMMAND, "CommandNode"),
cmd_name(cmd_name->gvalue()),
flag(util::mk_optional(flag)),
redirects(redirects),
args(args) {}
private:
std::string cmd_name;
std::optional<std::string> flag;
std::shared_ptr<RedirectsNode> redirects;
ArgumentVec args;
};
public:
static std::shared_ptr<CommandNode> build(std::list<Token>::iterator& it);
virtual void print(int indent) override;
virtual void execute(std::istream& in, std::ostream& out) override;
class PipeLineNode : public ExecutableNode {
public:
static std::shared_ptr<PipeLineNode> build(std::list<Token>::iterator& it);
virtual void print(int indent) override;
virtual void execute(std::istream &in, std::ostream &out) override;
protected:
CommandNode(TokenNode<TokenType::WORD>::shared cmd_name,
TokenNode<TokenType::FLAG>::shared flag,
ArgumentVec args,
std::shared_ptr<RedirectsNode> redirects) :
ExecutableNode(NodeType::COMMAND, "CommandNode"), cmd_name(cmd_name->gvalue()), flag(util::mk_optional(flag)),
redirects(redirects), args(args) {}
protected:
PipeLineNode(std::shared_ptr<CommandNode> l, std::shared_ptr<ExecutableNode> r)
: ExecutableNode(NodeType::PIPELINE_COMMAND, "PipeLine"),
l_command(l),
r_command(r) {}
private:
std::shared_ptr<ExecutableNode> l_command;
std::shared_ptr<ExecutableNode> r_command;
};
private:
std::string cmd_name;
std::optional<std::string> flag;
std::shared_ptr<RedirectsNode> redirects;
ArgumentVec args;
};
class PipeLineNode : public ExecutableNode {
public:
static std::shared_ptr<PipeLineNode> build(std::list<Token>::iterator& it);
virtual void print(int indent) override;
virtual void execute(std::istream& in, std::ostream& out) override;
class CommandLineNode : public ExecutableNode {
public:
static std::shared_ptr<CommandLineNode> build(std::list<Token>::iterator& it);
virtual void print(int indent) override;
virtual void execute(std::istream &in, std::ostream &out) override;
protected:
PipeLineNode(std::shared_ptr<CommandNode> l, std::shared_ptr<ExecutableNode> r) :
ExecutableNode(NodeType::PIPELINE_COMMAND, "PipeLine"), l_command(l), r_command(r) {}
protected:
CommandLineNode(std::shared_ptr<ExecutableNode> command, std::shared_ptr<ExecutableNode> pipe = nullptr)
: ExecutableNode(NodeType::COMMAND_LINE, "CommandLine"),
command(command),
pipe(pipe) {}
private:
std::shared_ptr<ExecutableNode> command;
std::shared_ptr<ExecutableNode> pipe;
};
private:
std::shared_ptr<ExecutableNode> l_command;
std::shared_ptr<ExecutableNode> r_command;
};
}
class CommandLineNode : public ExecutableNode {
public:
static std::shared_ptr<CommandLineNode> build(std::list<Token>::iterator& it);
virtual void print(int indent) override;
virtual void execute(std::istream& in, std::ostream& out) override;
protected:
CommandLineNode(std::shared_ptr<ExecutableNode> command, std::shared_ptr<ExecutableNode> pipe = nullptr) :
ExecutableNode(NodeType::COMMAND_LINE, "CommandLine"), command(command), pipe(pipe) {}
private:
std::shared_ptr<ExecutableNode> command;
std::shared_ptr<ExecutableNode> pipe;
};
} // namespace fsh

View File

@ -4,23 +4,21 @@
#include "ast/ast_base.hpp"
#include "util/text.hpp"
namespace fsh {
template<Lexer::TokenType T>
class TokenNode : public AstNode {
public:
using shared = std::shared_ptr<TokenNode>;
Lexer::TokenType gtoken_type() {return T;}
std::string& gvalue() {return value;};
static std::shared_ptr<TokenNode> build(std::list<Token>::iterator& it);
template <Lexer::TokenType T>
class TokenNode : public AstNode {
public:
using shared = std::shared_ptr<TokenNode>;
Lexer::TokenType gtoken_type() { return T; }
std::string& gvalue() { return value; };
static std::shared_ptr<TokenNode> build(std::list<Token>::iterator& it);
protected:
TokenNode(std::string value)
: AstNode(NodeType::TOKEN, util::tokens[T]), value(value) {}
protected:
TokenNode(std::string value) : AstNode(NodeType::TOKEN, util::tokens[T]), value(value) {}
private:
std::string value;
};
private:
std::string value;
};
}