Signed-off-by: erick-alcachofa <erick@artichoke.dev> Overhaul the expression parsing mechanism to utilize a Pratt (top-down operator precedence) parser. This change provides a more scalable and maintainable way to handle operator precedence and associativity compared to standard recursive descent. As part of this transition, the nomenclature for operators has been refined to reflect their position in the grammar (Prefix, Infix, Postfix) rather than their arity. * Renamed `UnaryOperator` and `UnaryExpression` to `PrefixOperator` and `PrefixExpression`. * Renamed `BinaryOperator` and `BinaryExpression` to `InfixOperator` and `InfixExpression`. * Renamed `ScopeAccessExpression` to `ModuleAccessExpression`. * Introduced `PostfixOperator` enum and associated logic for function calls, slicing, and reflection attributes. * Updated `toDot.cpp` and `toString.cpp` to support the new node types and renamed operators. * Added `Pratt.hpp` and `Pratt.cpp` to define `BindingPower` and map operators to their respective precedence levels. * Added `Operators.cpp` to handle token-to-operator mapping and classification (isPrefix, isInfix, isPostfix). * Refactored `Parser::parseExpression` to implement the core Pratt loop using binding power comparisons. * Moved literal parsing logic into a dedicated `Literals.cpp`. * Implemented explicit parsing methods for `Integer`, `Float`, `Char`, `String`, `Boolean`, and `Null` literals. * Added support for `this` and `_` (underscore) as identifier expressions. * **Prefix**: `!`, `-`, `~`, `&` (MemPtr), `*` (DerefPtr). * **Infix**: Arithmetic, Comparison, Bitwise, Logical, and all Compound Assignments. * **Postfix**: `()` (Call), `[]` (Slice/Access), `.#` (Slice length), `.*` (Slice pointer), and `.@` (Reflection). * **Missing Literals**: Struct literals and Array literals are not yet implemented in the new parsing flow. * **Node Specialization**: `MemberAccess`, `PointerMemberAccess`, and `ModuleAccess` currently use generic infix logic and need to be migrated to their specific AST node types. * **Error Handling**: Literal parsing (specifically `std::stold` and `std::stoul`) needs safety checks to prevent potential exceptions during conversion. * **Diagnostics**: Refine the error message for unexpected tokens in postfix expressions to explicitly list supported operators. * **Generic Ambiguity**: Generic type/function instantiation currently causes parsing conflicts with comparison operators (e.g., `Foo<T>`). This is a known issue that will be resolved by transitioning the grammar to a turbofish-style `::<...>` syntax.
49 lines
2.4 KiB
C++
49 lines
2.4 KiB
C++
//============================================================================//
|
|
// //
|
|
// artichoke programming language //
|
|
// //
|
|
// Copyright (C) 2025 Erick Saul Guzman Ramos, whoami.artichoke.dev //
|
|
// //
|
|
// //
|
|
// This program is free software: you can redistribute it and/or modify //
|
|
// it under the terms of the GNU Affero General Public License as published //
|
|
// by the Free Software Foundation, either version 3 of the License, or //
|
|
// (at your option) any later version. //
|
|
// //
|
|
// This program is distributed in the hope that it will be useful, //
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
|
// GNU Affero General Public License for more details. //
|
|
// //
|
|
// You should have received a copy of the GNU Affero General Public License //
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>. //
|
|
// //
|
|
//============================================================================//
|
|
|
|
#include <artichoke/Parser/Parser.hpp>
|
|
|
|
namespace arti::lang::pratt {
|
|
|
|
struct BindingPower {
|
|
std::uint16_t left;
|
|
std::uint16_t right;
|
|
};
|
|
|
|
ast::PostfixOperator getPostfixOperator(TokenV tokenType);
|
|
ast::PrefixOperator getPrefixOperator(TokenV tokenType);
|
|
ast::InfixOperator getInfixOperator(TokenV tokenType);
|
|
|
|
bool isPostfixOperator(TokenV tokenType);
|
|
bool isPrefixOperator(TokenV tokenType);
|
|
bool isInfixOperator(TokenV tokenType);
|
|
|
|
std::uint16_t postfixBindingPower(ast::PostfixOperator op);
|
|
std::uint16_t prefixBindingPower(ast::PrefixOperator op);
|
|
BindingPower infixBindingPower(ast::InfixOperator op);
|
|
|
|
bool isCompoundAssignOperator(ast::InfixOperator op);
|
|
|
|
ast::CompoundAssignOperator getCompoundOperatorType(ast::InfixOperator op);
|
|
|
|
}
|