summaryrefslogtreecommitdiffhomepage
path: root/Common/ParserKit.hpp
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2024-05-28 21:32:21 +0200
committerAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2024-05-28 21:32:21 +0200
commitebab1465b4d42910da1b36d8c65487c2f077b481 (patch)
tree22e6d280f7ce56a6c6e156294fdc276c6e27848b /Common/ParserKit.hpp
parent5e49fbae54bd7dcbf2e893acaef699ce9f2587f3 (diff)
MHR-21: refactors.
Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'Common/ParserKit.hpp')
-rw-r--r--Common/ParserKit.hpp171
1 files changed, 171 insertions, 0 deletions
diff --git a/Common/ParserKit.hpp b/Common/ParserKit.hpp
new file mode 100644
index 0000000..6e15c75
--- /dev/null
+++ b/Common/ParserKit.hpp
@@ -0,0 +1,171 @@
+/* -------------------------------------------
+
+ Copyright SoftwareLabs
+
+------------------------------------------- */
+
+#pragma once
+
+#include <Common/AsmKit/AsmKit.hpp>
+#include <vector>
+
+namespace ParserKit
+{
+ using namespace CompilerKit;
+
+ /// @brief Compiler backend, implements a frontend, such as C, C++...
+ /// See Toolchain, for some examples.
+ class CompilerBackend
+ {
+ public:
+ explicit CompilerBackend() = default;
+ virtual ~CompilerBackend() = default;
+
+ MPCC_COPY_DEFAULT(CompilerBackend);
+
+ // NOTE: cast this to your user defined ast.
+ typedef void* AstType;
+
+ //! @brief Compile a syntax tree ouf of the text.
+ //! Also takes the source file name for metadata.
+
+ virtual bool Compile(const std::string& text, const char* file) = 0;
+
+ //! @brief What language are we dealing with?
+ virtual const char* Language()
+ {
+ return "Invalid Language";
+ }
+ };
+
+ struct SyntaxLeafList;
+ struct SyntaxLeafList;
+ struct CompilerKeyword;
+
+ /// we want to do that because to separate keywords.
+ enum KeywordKind
+ {
+ eKeywordKindNamespace,
+ eKeywordKindFunctionStart,
+ eKeywordKindFunctionEnd,
+ eKeywordKindVariable,
+ eKeywordKindType,
+ eKeywordKindExpressionBegin,
+ eKeywordKindExpressionEnd,
+ eKeywordKindArgSeparator,
+ eKeywordKindBodyStart,
+ eKeywordKindBodyEnd,
+ eKeywordKindClass,
+ eKeywordKindPtrAccess,
+ eKeywordKindAccess,
+ eKeywordKindIf,
+ eKeywordKindElse,
+ eKeywordKindElseIf,
+ eKeywordKindVariableAssign,
+ eKeywordKindVariableDec,
+ eKeywordKindVariableInc,
+ eKeywordKindConstant,
+ eKeywordKindTypedef,
+ eKeywordKindEndInstr,
+ eKeywordKindSpecifier,
+ eKeywordKindInvalid,
+ eKeywordKindReturn,
+ eKeywordKindCommentInline,
+ eKeywordKindCommentMultiLineStart,
+ eKeywordKindCommentMultiLineEnd,
+ eKeywordKindEq,
+ eKeywordKindNotEq,
+ eKeywordKindGreaterEq,
+ eKeywordKindLessEq,
+ eKeywordKindPtr,
+ };
+
+ /// \brief Compiler keyword information struct.
+ struct CompilerKeyword
+ {
+ std::string keyword_name;
+ KeywordKind keyword_kind = eKeywordKindInvalid;
+ };
+ struct SyntaxLeafList final
+ {
+ struct SyntaxLeaf final
+ {
+ Int32 fUserType;
+#ifdef __PK_USE_STRUCT_INSTEAD__
+ CompilerKeyword fUserData;
+#else
+ std::string fUserData;
+#endif
+
+ std::string fUserValue;
+ struct SyntaxLeaf* fNext;
+ };
+
+ std::vector<SyntaxLeaf> fLeafList;
+ SizeType fNumLeafs;
+
+ size_t SizeOf()
+ {
+ return fNumLeafs;
+ }
+ std::vector<SyntaxLeaf>& Get()
+ {
+ return fLeafList;
+ }
+ SyntaxLeaf& At(size_t index)
+ {
+ return fLeafList[index];
+ }
+ };
+
+ /// find the perfect matching word in a haystack.
+ /// \param haystack base string
+ /// \param needle the string we search for.
+ /// \return if we found it or not.
+ inline bool find_word(const std::string& haystack,
+ const std::string& needle) noexcept
+ {
+ auto index = haystack.find(needle);
+
+ // check for needle validity.
+ if (index == std::string::npos)
+ return false;
+
+ // declare lambda
+ auto not_part_of_word = [&](int index) {
+ if (std::isspace(haystack[index]) || std::ispunct(haystack[index]))
+ return true;
+
+ if (index < 0 || index >= haystack.size())
+ return true;
+
+ return false;
+ };
+
+ return not_part_of_word(index - 1) && not_part_of_word(index + needle.size());
+ }
+
+ /// find a word within strict conditions and returns a range of it.
+ /// \param haystack
+ /// \param needle
+ /// \return position of needle.
+ inline std::size_t find_word_range(const std::string& haystack,
+ const std::string& needle) noexcept
+ {
+ auto index = haystack.find(needle);
+
+ // check for needle validity.
+ if (index == std::string::npos)
+ return false;
+
+ if (!isalnum((haystack[index + needle.size() + 1])) &&
+ !isdigit(haystack[index + needle.size() + 1]) &&
+ !isalnum((haystack[index - needle.size() - 1])) &&
+ !isdigit(haystack[index - needle.size() - 1]))
+ {
+ return index;
+ }
+
+ return false;
+ }
+} // namespace ParserKit