Add lexing and parsing exceptions and parse = and #=

This commit is contained in:
Username404 2021-07-29 17:35:35 +02:00
parent ecc2683cea
commit 905e7e7e82
Signed by: Username404-59
GPG Key ID: 7AB361FBB257A5D1
5 changed files with 65 additions and 13 deletions

View File

@ -1,5 +1,4 @@
#include "../headers/lex.hpp"
#include <iostream>
using namespace std;
tok::type getIdentifierCharType(const char& Char) {
@ -41,6 +40,7 @@ vector<tok> lex(const string& in)
for (;i < in.size(); ++i) {
tok::type currentCharType = getIdentifierCharType(in[i]);
bool isString = currentCharType == tok::STRING;
if (i == in.size() - 1 && not isString) throw tok::LexerException("A never ending string was found");
if ((currentCharType == type || isTypeString) && !isString) {
formedString += string(1, in[i]);
} else {

View File

@ -6,8 +6,20 @@
#define YBCON_VERSION "UNKNOWN"
#endif
#include <exception>
#include <string_view>
#include <string>
namespace Yerbacon {
consteval const char* getVersion() noexcept { return YBCON_VERSION; }
class Exception: public std::exception {
std::string exceptionCause;
[[nodiscard]] const char* what() const noexcept override {
return exceptionCause.data();
}
public:
explicit Exception(const std::string_view& cause): exceptionCause(cause) {}
};
}
#endif

View File

@ -2,11 +2,13 @@
#define YERBACON_LEX_H
#include <vector>
#include <string>
#include <string_view>
#include "Yerbacon.hpp"
#include <ostream>
struct tok {
class LexerException: public Yerbacon::Exception {
using Yerbacon::Exception::Exception;
};
enum type {
DEFINE, TAG, NUMBER, PLUS, LPAR, LBRACE, LBRACKET, RPAR, RBRACE, RBRACKET, ALPHACHAR, HYPHEN, LCOMP, RCOMP,
SQUOTE,

View File

@ -8,30 +8,47 @@ using namespace std;
#include "../lex.hpp"
class ParseComponent {};
struct ParseComponent {
virtual ~ParseComponent() = default;
};
class ParseTree: public ParseComponent {
private:
mutable unsigned int compCount = 0;
protected:
mutable vector<ParseComponent> subComponents;
public:
constexpr unsigned int getCompCount() const { return compCount; }
size_t getCompCount() const { return subComponents.size(); }
auto& getComponents() const { return subComponents; }
void add(const ParseComponent& component) const {
subComponents.push_back(component);
++compCount;
}; void addAll(const vector<ParseComponent>& components) const {
for (const auto& comp: components) add(comp);
}; void operator<<(const ParseComponent& component) const { add(component); }
explicit ParseTree(const ParseComponent& element): subComponents() { add(element); }
ParseTree(const initializer_list<ParseComponent>& elements): subComponents() { addAll(elements); }
ParseTree(): subComponents() {};
~ParseTree() = default;
};
namespace StandardComponents::types {
namespace StandardComponents {
struct [[deprecated]] Expression: ParseComponent {};
struct Define: ParseComponent {
const bool final;
explicit Define(const bool& isFinal): final(isFinal) {}
// Shorthand for Define(false)
Define(): Define(false) {}
};
struct Constructor: ParseComponent {};
struct ClassBody: ParseComponent {};
struct Class: ParseComponent {
string bullshitText;
Constructor constructor;
explicit Class(string_view text): bullshitText(text) {}
};
namespace types {
struct String: ParseComponent {
[[maybe_unused]] const char* content;
explicit String(const char* string): content(string) {}
};
}
}
#endif //YERBACON_PARSECOMPONENTS_HPP

View File

@ -4,18 +4,39 @@
#include <string>
#include "../lex.hpp"
#include "../parsing/ParseComponents.hpp"
#include "../Yerbacon.hpp"
namespace Parser {
class ParsingException: public Yerbacon::Exception {
using Yerbacon::Exception::Exception;
};
ParseTree parseVector(const vector<tok>& lexed) {
ParseTree parseTree;
using namespace StandardComponents::types;
using namespace StandardComponents;
if (lexed.size() > 1) {
for (unsigned int i = 0; i < lexed.size() - 1; ++i) {
const auto& current = lexed[i], next = lexed[i + 1];
switch (current.toktype) {
case tok::STRING: parseTree << types::String(current.toktext.data()); break;
case tok::IDENTIFIER: {
if (current.toktext == "class") {
if (next.toktype == tok::IDENTIFIER) {
parseTree << Class(next.toktext);
++i; continue;
} else throw ParsingException('"' + next.toktext + "\" is not a valid class identifier");
} else {
if (next.toktype == tok::TAG && (lexed.size() - i) > 2 && lexed[i + 2].toktype == tok::DEFINE) {
parseTree << Define(true); i += 2;
} else if (next.toktype == tok::DEFINE) {
parseTree << Define(); ++i;
}
}
}
default: break;
}
}
} else throw ParsingException("At least 2 tokens must be provided");
return parseTree;
}
}