Skip to content
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
128 changes: 91 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ The sQeeZ Parser is responsible for analyzing the sequence of tokens generated b
- [Expressions](#expressions)
- [Overview of the Node Types](#overview-of-the-node-types)
- [Order of Precedence](#order-of-precedence)
- [Operator Precedence Levels](#operator-precedence-levels)
- [Parsing Functions Overview](#parsing-functions-overview)

# How to Use
> **Note:**
Expand Down Expand Up @@ -184,16 +186,17 @@ enum class NodeType {
FunctionDeclaration,
ReturnStmt,
VarDeclaration,
ConditionalStatement,
WhileStatement,
DoWhileStatement,
ForStatement,
ForInStatement,
ForOfStatement,
ConditionalStmt,
WhileStmt,
DoWhileStmt,
ForStmt,
ForInStmt,
ForOfStmt,
LogStmt,
// EXPRESSIONS
AssignmentExpr,
CompoundAssignmentExpr,
CallbackFunctionExpr,
TernaryExpr,
BinaryExpr,
UnaryExpr,
Expand All @@ -212,42 +215,93 @@ enum class NodeType {
StringLiteral,
HexCodeLiteral,
// Short Notation
ShortOperationLiteral,
ShortSingleExpressionLiteral,
ShortDoubleExpressionLiteral
ShortOperationLiteral
};
```

# Order of Precedence
The order of precedence dictates how operators are parsed and evaluated in expressions, which is vital for constructing accurate Abstract Syntax Trees (AST). The parser employs recursive descent parsing, where each level of the tree represents different precedence levels. This recursive nature allows for a clear and structured representation of nested expressions, ensuring that operations are performed in the correct order according to their precedence.

1. **Primary Expressions**
- Literals, Identifiers, parenthesized expressions.
2. **Short Notation (Data)**
- `@` (short notation for objects and arrays)
2. **Short Notation (Functions)**
- `MAP`, `FILTER`, `REDUCE`, etc.
3. **Member Access**
- `.` (dot notation) and `[]` (bracket notation)
4. **Function Calls**
- `()` (function call)
5. **Unary Operators**
- `++`, `--` (pre-increment and pre-decrement)
6. **Exponentiation**
- `**` (power operator)
7. **Multiplicative Operators**
- `*`, `/`, `%` (multiplication, division, modulus)
8. **Additive Operators**
- `+`, `-` (addition and subtraction)
9. **Relational Operators**
- `<`, `<=`, `>`, `>=` (comparison)
10. **Equality Operators**
- `==`, `!=` (equality checks)
11. **Logical Operators**
- `&&`, `||` (logical AND and OR)
12. **Conditional Operator**
- `? :` (ternary operator)
13. **Assignment Operators**
- `=`, `+=`, `-=`, `*=`, `/=`, `%=`, etc. (assignment)
## Operator Precedence Levels

1. **Primary Expressions**
- Literals, Identifiers, Parenthesized expressions (`parsePrimaryExpr`)

2. **Short Notation (Data)**
- `@` (short notation for objects and arrays) (`parseShortData`)

3. **Short Notation (Functions)**
- `MAP`, `FILTER`, `REDUCE`, etc. (`parseCallbackFunctionExpr`)

4. **Member Access**
- `.` (dot notation), `[]` (bracket notation), `|>` (pipe notation) (`parseMemberExpr`)

5. **Function Calls**
- `()` (function call) (`parseCallExpr`, `parseCallMemberExpr`)

6. **Unary Operators**
- `++`, `--` (pre-increment and pre-decrement)

7. **Exponentiation**
- `**` (power operator) (`parsePowerExpr`)

8. **Multiplicative Operators**
- `*`, `/`, `%` (multiplication, division, modulus) (`parseMultiplicativeExpr`)

9. **Additive Operators**
- `+`, `-` (addition and subtraction) (`parseAdditiveExpr`)

10. **Relational Operators**
- `<`, `<=`, `>`, `>=` (comparison) (`parseRelationalExpr`)

11. **Equality Operators**
- `==`, `!=` (equality checks) (`parseEqualityExpr`)

12. **Logical Operators**
- `&&`, `||` (logical AND and OR) (`parseLogicalExpr`)

13. **Conditional Operator**
- `? :` (ternary operator) (`parseTernaryExpr`)

14. **Assignment Operators**
- `=`, `+=`, `-=`, `*=`, `/=`, `%=`, etc. (`parseAssignmentExpr`)

## Parsing Functions Overview

### Statements
- `parseStatement()`
- `parseStatementBlock()`
- `parseFunctionDeclaration()`
- `parseReturnStatement()`
- `parseVarDeclaration()`
- `parseConditionalStatement()`
- `parseWhileStatement()`
- `parseDoWhileStatement()`
- `parseForStatement()`
- `parseLogStatement()`

### Expressions
- `parseExpression()`
- `parseAssignmentExpr()`
- `parseTernaryExpr()`
- `parseLogicalExpr()`
- `parseEqualityExpr()`
- `parseRelationalExpr()`
- `parseObjectExpr()`
- `parseArrayExpr()`
- `parseCallbackFunctionExpr()`
- `parseShortData()`
- `parseAdditiveExpr()`
- `parseMultiplicativeExpr()`
- `parsePowerExpr()`
- `parseCallMemberExpr()`
- `parseCallExpr(caller, method)`
- `parseShortExpr(caller, method)`
- `parseArgs()`
- `parseShortArgs()`
- `parseArgumentsList()`
- `parseMemberExpr()`
- `parsePrimaryExpr()`


[Back to Top](#sqeez-parser)
81 changes: 20 additions & 61 deletions include/parser/ast_nodes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,7 @@ enum class NodeType {
StringLiteral,
HexCodeLiteral,
// Short Notation
ShortOperationLiteral,
ShortSingleExpressionLiteral,
ShortDoubleExpressionLiteral
ShortOperationLiteral
};

// Base class for all AST nodes
Expand Down Expand Up @@ -371,10 +369,10 @@ class ForOfStmt : public Stmt {
class LogStmt : public Stmt {
public:
Token logType;
std::unique_ptr<Expr> message;
std::vector<std::unique_ptr<Expr>> message;
std::unique_ptr<Expr> color;

LogStmt(const Token& logType, std::unique_ptr<Expr> message, std::unique_ptr<Expr> color = nullptr)
LogStmt(const Token& logType, std::vector<std::unique_ptr<Expr>> message, std::unique_ptr<Expr> color = nullptr)
: Stmt(NodeType::LogStmt), logType(logType), message(std::move(message)), color(std::move(color)) {}

LogStmt(const LogStmt&) = delete;
Expand All @@ -383,13 +381,19 @@ class LogStmt : public Stmt {
LogStmt& operator=(LogStmt&&) noexcept = default;

virtual std::string toString() const override {
std::stringstream ss;
ss << logType.plainText << "(" << message->toString();
std::string result = "LogStmt: ";
result += logType.value + "(";
for (size_t i = 0; i < message.size(); ++i) {
result += message[i]->toString();
if (i < message.size() - 1) {
result += ", ";
}
}
result += ")";
if (color) {
ss << ", " << color->toString();
result += " in " + color->toString();
}
ss << ")";
return ss.str();
return result;
}
};

Expand Down Expand Up @@ -768,65 +772,20 @@ class HexCodeLiteral : public Expr {
std::string toString() const override { return "HexCodeLiteral: " + value; }
};

// Short Notation
class ShortOperationLiteral : public Expr {
public:
Token type;
Token operation_;
std::unique_ptr<Expr> value;
Token operation;
std::unique_ptr<Expr> operand;

ShortOperationLiteral(const Token& type, const Token& operation_, std::unique_ptr<Expr> value)
: Expr(NodeType::ShortOperationLiteral), type(type), operation_(operation_), value(std::move(value)) {}
ShortOperationLiteral(const Token& operation, std::unique_ptr<Expr> operand)
: Expr(NodeType::ShortOperationLiteral), operation(operation), operand(std::move(operand)) {}

ShortOperationLiteral(const ShortOperationLiteral&) = delete;
ShortOperationLiteral& operator=(const ShortOperationLiteral&) = delete;
ShortOperationLiteral(ShortOperationLiteral&&) noexcept = default;
ShortOperationLiteral& operator=(ShortOperationLiteral&&) = default;

std::string toString() const override {
return "ShortOperationLiteral: " + type.plainText + "(" + operation_.value + value->toString() + ")";
}
};

class ShortSingleExpressionLiteral : public Expr {
public:
Token type;
std::unique_ptr<Expr> value;

ShortSingleExpressionLiteral(const Token& type, std::unique_ptr<Expr> value)
: Expr(NodeType::ShortSingleExpressionLiteral), type(type), value(std::move(value)) {}

ShortSingleExpressionLiteral(const ShortSingleExpressionLiteral&) = delete;
ShortSingleExpressionLiteral& operator=(const ShortSingleExpressionLiteral&) = delete;
ShortSingleExpressionLiteral(ShortSingleExpressionLiteral&&) noexcept = default;
ShortSingleExpressionLiteral& operator=(ShortSingleExpressionLiteral&&) = default;

std::string toString() const override {
return "ShortSingleExpressionLiteral: " + type.plainText + "(" + value->toString() + ")";
}
};
ShortOperationLiteral& operator=(ShortOperationLiteral&&) noexcept = default;

class ShortDoubleExpressionLiteral : public Expr {
public:
Token type;
std::unique_ptr<Expr> value1;
std::unique_ptr<Expr> value2;

ShortDoubleExpressionLiteral(const Token& type, std::unique_ptr<Expr> value1, std::unique_ptr<Expr> value2)
: Expr(NodeType::ShortDoubleExpressionLiteral),
type(type),
value1(std::move(value1)),
value2(std::move(value2)) {}

ShortDoubleExpressionLiteral(const ShortDoubleExpressionLiteral&) = delete;
ShortDoubleExpressionLiteral& operator=(const ShortDoubleExpressionLiteral&) = delete;
ShortDoubleExpressionLiteral(ShortDoubleExpressionLiteral&&) noexcept = default;
ShortDoubleExpressionLiteral& operator=(ShortDoubleExpressionLiteral&&) = default;

std::string toString() const override {
return "ShortDoubleExpressionLiteral: " + type.plainText + "(" + value1->toString() + ", " + value2->toString() +
")";
}
std::string toString() const override { return "ShortOperationLiteral: " + operation.value + operand->toString(); }
};

#endif // AST_NODES_HPP
56 changes: 54 additions & 2 deletions include/parser/parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ class Parser {
std::unique_ptr<Expr> parseLogicalExpr();
std::unique_ptr<Expr> parseEqualityExpr();
std::unique_ptr<Expr> parseRelationalExpr();
std::unique_ptr<Expr> parsePipeExpr();
std::unique_ptr<Expr> parseObjectExpr();
std::unique_ptr<Expr> parseArrayExpr();
std::unique_ptr<Expr> parseCallbackFunctionExpr();
Expand All @@ -47,11 +46,12 @@ class Parser {
std::unique_ptr<Expr> parsePowerExpr();
std::unique_ptr<Expr> parseCallMemberExpr();
std::unique_ptr<Expr> parseCallExpr(std::unique_ptr<Expr> caller, std::unique_ptr<Expr> method);
std::unique_ptr<Expr> parseShortExpr(std::unique_ptr<Expr> caller, std::unique_ptr<Expr> method);
std::vector<std::unique_ptr<Expr>> parseArgs();
std::vector<std::unique_ptr<Expr>> parseShortArgs();
std::vector<std::unique_ptr<Expr>> parseArgumentsList();
std::unique_ptr<Expr> parseMemberExpr();
std::unique_ptr<Expr> parsePrimaryExpr();
std::unique_ptr<Expr> parseShortExpr();

// Utility functions
bool isEOF();
Expand All @@ -62,6 +62,58 @@ class Parser {
void log(const std::unique_ptr<Program>& program, bool devMode);
void skipSemicolon();
void skipComment();
inline static const std::unordered_map<ShortNotationToken, std::string> shortEnumToString = {
{ShortNotationToken::LENGTH, "length"},
{ShortNotationToken::CONCAT, "concat"},
{ShortNotationToken::INCLUDES, "includes"},
{ShortNotationToken::INDEX_OF, "indexOf"},
{ShortNotationToken::LAST_INDEX_OF, "lastIndexOf"},
{ShortNotationToken::SLICE, "slice"},
{ShortNotationToken::PUSH, "push"},
{ShortNotationToken::POP, "pop"},
{ShortNotationToken::SHIFT, "shift"},
{ShortNotationToken::UNSHIFT, "unshift"},
{ShortNotationToken::SPLICE, "splice"},
{ShortNotationToken::REVERSE, "reverse"},
{ShortNotationToken::SORT, "sort"},
{ShortNotationToken::FILL, "fill"},
{ShortNotationToken::JOIN, "join"},
{ShortNotationToken::COUNT, "count"},
{ShortNotationToken::EVERY, "every"},
{ShortNotationToken::SOME, "some"},
{ShortNotationToken::FIND, "find"},
{ShortNotationToken::FIND_INDEX, "findIndex"},
{ShortNotationToken::FIND_LAST, "findLast"},
{ShortNotationToken::FIND_LAST_INDEX, "findLastIndex"},
{ShortNotationToken::FILTER, "filter"},
{ShortNotationToken::MAP, "map"},
{ShortNotationToken::REDUCE, "reduce"},
{ShortNotationToken::FLAT, "flat"},
{ShortNotationToken::FLAT_MAP, "flatMap"},
{ShortNotationToken::FOR_EACH, "forEach"},
{ShortNotationToken::HAS_KEY, "hasKey"},
{ShortNotationToken::KEYS, "keys"},
{ShortNotationToken::VALUES, "values"},
{ShortNotationToken::ENTRIES, "entries"},
{ShortNotationToken::GET, "get"},
{ShortNotationToken::CHAR_AT, "charAt"},
{ShortNotationToken::CHAR_CODE_AT, "charCodeAt"},
{ShortNotationToken::MATCH, "match"},
{ShortNotationToken::MATCH_ALL, "matchAll"},
{ShortNotationToken::PAD_END, "padEnd"},
{ShortNotationToken::PAD_START, "padStart"},
{ShortNotationToken::REPEAT, "repeat"},
{ShortNotationToken::REPLACE, "replace"},
{ShortNotationToken::REPLACE_ALL, "replaceAll"},
{ShortNotationToken::SPLIT, "split"},
{ShortNotationToken::STARTS_WITH, "startsWith"},
{ShortNotationToken::ENDS_WITH, "endsWith"},
{ShortNotationToken::SUBSTRING, "substring"},
{ShortNotationToken::LOWERCASE, "lowercase"},
{ShortNotationToken::UPPERCASE, "uppercase"},
{ShortNotationToken::TRIM, "trim"},
{ShortNotationToken::TRIM_END, "trimEnd"},
{ShortNotationToken::TRIM_START, "trimStart"}};
};

#endif // PARSER_HPP
Loading
Loading