Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parser 2.0 #55

Merged
merged 7 commits into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ add_library(Lexer STATIC ${SOURCES_LEXER})
target_include_directories(Lexer PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/CuriousX/Lexer)
target_link_libraries(Lexer PUBLIC Utils nlohmann_json::nlohmann_json)

# # -------------------- Include Parser Folder--------------------------------
# add_library(Parser STATIC ${SOURCES_PARSER})
# target_include_directories(Parser PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/CuriousX/Parser)
# target_link_libraries(Parser PUBLIC Lexer)
# -------------------- Include Parser Folder--------------------------------
add_library(Parser STATIC ${SOURCES_PARSER})
target_include_directories(Parser PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/CuriousX/Parser)
target_link_libraries(Parser PUBLIC Lexer)

# # -------------------- Include Semantic Folder--------------------------------
# add_library(Semantic STATIC ${SOURCES_SEMANTIC})
Expand All @@ -67,7 +67,7 @@ target_link_libraries(Lexer PUBLIC Utils nlohmann_json::nlohmann_json)

# -------------------- Create the main executable and link it to the libraries --------------------------------
add_executable(CuriousX "CuriousX/main.cpp")
target_link_libraries(CuriousX PRIVATE Lexer)
target_link_libraries(CuriousX PRIVATE Parser)
target_include_directories(CuriousX PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/CuriousX)


Expand Down
26 changes: 12 additions & 14 deletions CuriousX/Lexer/Lexer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#include <string_view>
#include <unordered_map>

#include "Error.hpp"
#include "LexerToken.hpp"

class Lexer
Expand All @@ -19,21 +18,12 @@ class Lexer
do
{
t = nextToken();
} while (t.type == LexerTokenType::Space || t.type == LexerTokenType::Tab ||
t.type == LexerTokenType::Newline);
} while (t.type == LexerTokenType::Space || t.type == LexerTokenType::Tab);
return t;
}

LexerToken nextToken() { return doGetNextToken(); }

SourceLocation currentLocation() const { return SourceLocation(y_pos, x_pos); }

static bool isInt(std::string_view data)
{
return std::all_of(data.begin(), data.end(),
[](char c) { return std::isdigit(static_cast<unsigned char>(c)); });
}

private:
std::string_view data;
size_t pos = 0;
Expand Down Expand Up @@ -81,6 +71,14 @@ class Lexer

char peek_next_char() const { return pos < data.size() ? data[pos] : '\0'; }

SourceLocation currentLocation() const { return SourceLocation(y_pos, x_pos); }

static bool isInt(std::string_view data)
{
return std::all_of(data.begin(), data.end(),
[](char c) { return std::isdigit(static_cast<unsigned char>(c)); });
}

LexerToken handleComment(size_t startPos, const SourceLocation& location)
{
while (true)
Expand All @@ -102,7 +100,7 @@ class Lexer
// Map of single-character tokens
static const std::unordered_map<char, std::pair<std::string_view, LexerTokenType>>
singleCharTokens = {{'\0', {"\0", LexerTokenType::Eof}},
{'\n', {"\n", LexerTokenType::Newline}},
{'\n', {"\\n", LexerTokenType::Newline}},
{'\t', {"\t", LexerTokenType::Tab}},
{'(', {"(", LexerTokenType::ParenOpen}},
{')', {")", LexerTokenType::ParenClose}},
Expand All @@ -128,7 +126,7 @@ class Lexer
{
if (next_char() == '=')
return {data.substr(startPos, 2), location, LexerTokenType::NotEqualToken};
throw Error("Unexpected character after '!' at line ", location);
throw Error(" Lexical Error- Unexpected character after '!' at line ", location);
}

if (nchar == '>')
Expand Down Expand Up @@ -168,7 +166,7 @@ class Lexer

if (!(std::isalpha(nchar) || std::isdigit(nchar)))
{
throw Error("Unknown character at line ", location);
throw Error(" Lexical Error- Unknown character at line ", location);
}

// Handle numeric and keyword tokens
Expand Down
2 changes: 2 additions & 0 deletions CuriousX/Lexer/LexerToken.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "SourceLocation.hpp"
#include "Error.hpp"
#include <string_view>

enum class LexerTokenType
Expand Down Expand Up @@ -39,6 +40,7 @@ enum class LexerTokenType
Newline,
Eof,

ProgramToken,
Unknown
};

Expand Down
109 changes: 70 additions & 39 deletions CuriousX/Parser/Node.hpp
Original file line number Diff line number Diff line change
@@ -1,51 +1,82 @@
#ifndef NODE_HPP
#define NODE_HPP

#include <iomanip>
#include <memory>
#include <queue>
#include <variant>

#include "Error.hpp"
#include "LexerToken.hpp"
#include <memory>
#include <vector>

enum class InferredType { INTEGER, FLOAT };

struct Node
enum class NodeType
{
std::shared_ptr<Node> left;
std::shared_ptr<Node> right;
LexerToken type;
std::variant<InferredType, std::monostate> inferredType;
BinaryOperation,
ConditionalOperation,
PrintProgram,
};

// Build and return a generic AST node
inline std::shared_ptr<Node> makeNode(std::shared_ptr<Node> left, std::shared_ptr<Node> right, const LexerToken &type)
class ASTNode
{
std::shared_ptr<Node> node = std::make_shared<Node>();

node->left = left;
node->right = right;
node->type = type;
node->inferredType = std::monostate{};

return node;
}
public:
ASTNode(const LexerToken& token) : token(token) {}
virtual ~ASTNode() = default;
virtual NodeType getType() const = 0;
LexerToken token;
};

// Make an AST leaf node
inline std::shared_ptr<Node> makeLeaf(const LexerToken &type) { return (makeNode(nullptr, nullptr, type)); }
class BinaryNode : public ASTNode
{
public:
BinaryNode(std::unique_ptr<ASTNode> left, std::unique_ptr<ASTNode> right,
const LexerToken& token)
: ASTNode(token), left(std::move(left)), right(std::move(right))
{
}
NodeType getType() const override { return NodeType::BinaryOperation; }
std::unique_ptr<ASTNode> left;
std::unique_ptr<ASTNode> right;
};

// Make a unary AST node: only one child
inline std::shared_ptr<Node> makeUnary(std::shared_ptr<Node> left, const LexerToken &type)
class ConditionalNode : public ASTNode
{
return (makeNode(left, nullptr, type));
}
public:
ConditionalNode(std::unique_ptr<ASTNode> condition, std::unique_ptr<ASTNode> ifNode,
std::unique_ptr<ASTNode> elseNode, const LexerToken& token)
: ASTNode(token), condition(std::move(condition)), ifNode(std::move(ifNode)),
elseNode(std::move(elseNode))
{
}
NodeType getType() const override { return NodeType::ConditionalOperation; }
std::unique_ptr<ASTNode> condition;
std::unique_ptr<ASTNode> ifNode;
std::unique_ptr<ASTNode> elseNode;
};

// Get height of tree
inline int TreeHeight(std::shared_ptr<Node> node)
class TreeNode : public ASTNode
{
if (!node) return 0;
return 1 + std::max(TreeHeight(node->left), TreeHeight(node->right));
}
public:
TreeNode(std::vector<std::unique_ptr<ASTNode>> children, const LexerToken& token)
: ASTNode(token), children(std::move(children))
{
}
NodeType getType() const override { return NodeType::PrintProgram; }
std::vector<std::unique_ptr<ASTNode>> children;
};

#endif
class ASTNodeFactory
{
public:
static std::unique_ptr<BinaryNode> createBinaryNode(std::unique_ptr<ASTNode> left,
std::unique_ptr<ASTNode> right,
const LexerToken& token)
{
return std::make_unique<BinaryNode>(std::move(left), std::move(right), token);
}
static std::unique_ptr<ASTNode> createConditionalNode(std::unique_ptr<ASTNode> condition,
std::unique_ptr<ASTNode> ifNode,
std::unique_ptr<ASTNode> elseNode,
const LexerToken& token)
{
return std::make_unique<ConditionalNode>(std::move(condition), std::move(ifNode),
std::move(elseNode), token);
}
static std::unique_ptr<TreeNode> createTreeNode(std::vector<std::unique_ptr<ASTNode>> children,
const LexerToken& token)
{
return std::make_unique<TreeNode>(std::move(children), token);
}
};
Loading