完成Parser定义以及表达式解析
This commit is contained in:
@@ -6,3 +6,9 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Ast/Expr/IdentiExpr.hpp>
|
||||
#include <Ast/Expr/InfixExpr.hpp>
|
||||
#include <Ast/Expr/LiteralExpr.hpp>
|
||||
#include <Ast/Expr/PrefixExpr.hpp>
|
||||
|
||||
|
||||
@@ -21,14 +21,15 @@ namespace Fig
|
||||
|
||||
IdentiExpr, // 标识符表达式
|
||||
LiteralExpr, // 字面量表达式
|
||||
UnaryExpr, // 一元表达式
|
||||
BinaryExpr, // 二元表达式
|
||||
TernaryExpr, // 三元表达式
|
||||
PrefixExpr, // 一元 前缀表达式
|
||||
InfixExpr, // 二元 中缀表达式
|
||||
};
|
||||
struct AstNode
|
||||
{
|
||||
AstType type = AstType::AstNode;
|
||||
SourceLocation location;
|
||||
|
||||
virtual String toString() const = 0;
|
||||
};
|
||||
|
||||
struct Expr : public AstNode
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Ast/Base.hpp>
|
||||
#include <Deps/Deps.hpp>
|
||||
|
||||
namespace Fig
|
||||
{
|
||||
@@ -25,5 +27,10 @@ namespace Fig
|
||||
name = std::move(_name);
|
||||
location = std::move(_loc);
|
||||
}
|
||||
|
||||
virtual String toString() const override
|
||||
{
|
||||
return std::format("<IdentiExpr: {}>", name);
|
||||
}
|
||||
};
|
||||
};
|
||||
39
src/Ast/Expr/InfixExpr.hpp
Normal file
39
src/Ast/Expr/InfixExpr.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
/*!
|
||||
@file src/Ast/Expr/InfixExpr.hpp
|
||||
@brief 中缀表达式定义
|
||||
@author PuqiAR (im@puqiar.top)
|
||||
@date 2026-02-14
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Ast/Base.hpp>
|
||||
#include <Ast/Operator.hpp>
|
||||
|
||||
#include <Deps/Deps.hpp>
|
||||
|
||||
namespace Fig
|
||||
{
|
||||
struct InfixExpr final : Expr
|
||||
{
|
||||
Expr *left;
|
||||
BinaryOperator op;
|
||||
Expr *right;
|
||||
|
||||
InfixExpr()
|
||||
{
|
||||
type = AstType::InfixExpr;
|
||||
}
|
||||
InfixExpr(Expr *_left, BinaryOperator _op, Expr *_right) :
|
||||
left(_left), op(_op), right(_right)
|
||||
{
|
||||
type = AstType::InfixExpr;
|
||||
location = _left->location;
|
||||
}
|
||||
|
||||
virtual String toString() const override
|
||||
{
|
||||
return std::format("<InfixExpr: '{}' {} '{}'>", left->toString(), magic_enum::enum_name(op), right->toString());
|
||||
}
|
||||
};
|
||||
}; // namespace Fig
|
||||
@@ -10,6 +10,8 @@
|
||||
#include <Ast/Base.hpp>
|
||||
#include <Token/Token.hpp>
|
||||
|
||||
#include <Deps/Deps.hpp>
|
||||
|
||||
namespace Fig
|
||||
{
|
||||
struct LiteralExpr final : Expr
|
||||
@@ -20,9 +22,15 @@ namespace Fig
|
||||
{
|
||||
type = AstType::LiteralExpr;
|
||||
}
|
||||
LiteralExpr(const Token& token) : token(token)
|
||||
LiteralExpr(const Token& token, SourceLocation _location) : token(token)
|
||||
{
|
||||
type = AstType::LiteralExpr;
|
||||
location = std::move(_location);
|
||||
}
|
||||
|
||||
virtual String toString() const override
|
||||
{
|
||||
return std::format("<LiteralExpr: {}>", magic_enum::enum_name(token.type));
|
||||
}
|
||||
};
|
||||
}; // namespace Fig
|
||||
39
src/Ast/Expr/PrefixExpr.hpp
Normal file
39
src/Ast/Expr/PrefixExpr.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
/*!
|
||||
@file src/Ast/Expr/PrefixExpr.hpp
|
||||
@brief 前缀表达式定义
|
||||
@author PuqiAR (im@puqiar.top)
|
||||
@date 2026-02-14
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Ast/Operator.hpp>
|
||||
#include <Ast/Base.hpp>
|
||||
|
||||
#include <Deps/Deps.hpp>
|
||||
|
||||
namespace Fig
|
||||
{
|
||||
struct PrefixExpr final : Expr
|
||||
{
|
||||
UnaryOperator op;
|
||||
Expr *operand;
|
||||
|
||||
PrefixExpr()
|
||||
{
|
||||
type = AstType::PrefixExpr;
|
||||
}
|
||||
|
||||
PrefixExpr(UnaryOperator _op, Expr *_operand) :
|
||||
op(_op), operand(_operand)
|
||||
{
|
||||
type = AstType::PrefixExpr;
|
||||
location = _operand->location;
|
||||
}
|
||||
|
||||
virtual String toString() const override
|
||||
{
|
||||
return std::format("<PrefixExpr: {} '{}'>", magic_enum::enum_name(op), operand->toString());
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -22,8 +22,10 @@ namespace Fig
|
||||
|
||||
HashMap<TokenType, BinaryOperator> &GetBinaryOpMap()
|
||||
{
|
||||
static HashMap<TokenType, BinaryOperator> binaryOpMap{{TokenType::Plus, BinaryOperator::Add},
|
||||
static HashMap<TokenType, BinaryOperator> binaryOpMap{
|
||||
{TokenType::Plus, BinaryOperator::Add},
|
||||
{TokenType::Minus, BinaryOperator::Subtract},
|
||||
{TokenType::Asterisk, BinaryOperator::Multiply},
|
||||
{TokenType::Slash, BinaryOperator::Divide},
|
||||
{TokenType::Percent, BinaryOperator::Modulo},
|
||||
|
||||
@@ -42,30 +44,54 @@ namespace Fig
|
||||
{TokenType::Power, BinaryOperator::Power},
|
||||
|
||||
{TokenType::Assign, BinaryOperator::Assign},
|
||||
{TokenType::PlusEqual, BinaryOperator::AddAssign},
|
||||
{TokenType::MinusEqual, BinaryOperator::SubAssign},
|
||||
{TokenType::AsteriskEqual, BinaryOperator::MultiplyAssign},
|
||||
{TokenType::SlashEqual, BinaryOperator::DivideAssign},
|
||||
{TokenType::PercentEqual, BinaryOperator::ModuloAssign},
|
||||
{TokenType::CaretEqual, BinaryOperator::BitXorAssign},
|
||||
|
||||
{TokenType::Pipe, BinaryOperator::BitAnd},
|
||||
{TokenType::Ampersand, BinaryOperator::BitAnd},
|
||||
{TokenType::ShiftLeft, BinaryOperator::ShiftLeft},
|
||||
{TokenType::ShiftRight, BinaryOperator::ShiftRight}};
|
||||
{TokenType::ShiftRight, BinaryOperator::ShiftRight},
|
||||
|
||||
{TokenType::Dot, BinaryOperator::MemberAccess},
|
||||
};
|
||||
return binaryOpMap;
|
||||
}
|
||||
|
||||
// 赋值 < 三元 < 逻辑或 < 逻辑与 < 位运算 < 比较 < 位移 < 加减 < 乘除 < 幂 < 一元
|
||||
// 赋值 < 三元 < 逻辑或 < 逻辑与 < 位运算 < 比较 < 位移 < 加减 < 乘除 < 幂 < 一元 < 成员访问 < (后缀)
|
||||
|
||||
/*
|
||||
暂划分:
|
||||
二元运算符:0 - 20000
|
||||
一元运算符:20001 - 40000
|
||||
后缀/成员/其他:40001 - 60001
|
||||
|
||||
*/
|
||||
|
||||
HashMap<UnaryOperator, BindingPower> &GetUnaryOpBindingPowerMap()
|
||||
{
|
||||
static HashMap<UnaryOperator, BindingPower> unbpm{
|
||||
{UnaryOperator::BitNot, 10000},
|
||||
{UnaryOperator::Negate, 10000},
|
||||
{UnaryOperator::Not, 10000},
|
||||
{UnaryOperator::AddressOf, 10000},
|
||||
{UnaryOperator::BitNot, 20001},
|
||||
{UnaryOperator::Negate, 20001},
|
||||
{UnaryOperator::Not, 20001},
|
||||
{UnaryOperator::AddressOf, 20001},
|
||||
};
|
||||
return unbpm;
|
||||
}
|
||||
|
||||
HashMap<BinaryOperator, BindingPower> &GetBinaryOpBindingPowerMap()
|
||||
{
|
||||
static HashMap<BinaryOperator, BindingPower> bnbpm{{BinaryOperator::Assign, 100},
|
||||
static HashMap<BinaryOperator, BindingPower> bnbpm{
|
||||
{BinaryOperator::Assign, 100},
|
||||
{BinaryOperator::AddAssign, 100},
|
||||
{BinaryOperator::SubAssign, 100},
|
||||
{BinaryOperator::MultiplyAssign, 100},
|
||||
{BinaryOperator::DivideAssign, 100},
|
||||
{BinaryOperator::ModuloAssign, 100},
|
||||
{BinaryOperator::BitXorAssign, 100},
|
||||
|
||||
{BinaryOperator::LogicalOr, 500},
|
||||
{BinaryOperator::LogicalAnd, 550},
|
||||
@@ -93,8 +119,51 @@ namespace Fig
|
||||
{BinaryOperator::Divide, 4500},
|
||||
|
||||
{BinaryOperator::Power, 5000},
|
||||
|
||||
{BinaryOperator::MemberAccess, 40001},
|
||||
};
|
||||
return bnbpm;
|
||||
}
|
||||
|
||||
BindingPower GetUnaryOpRBp(UnaryOperator op)
|
||||
{
|
||||
return GetUnaryOpBindingPowerMap().at(op);
|
||||
}
|
||||
|
||||
BindingPower GetBinaryOpLBp(BinaryOperator op)
|
||||
{
|
||||
return GetBinaryOpBindingPowerMap().at(op);
|
||||
}
|
||||
|
||||
BindingPower GetBinaryOpRBp(BinaryOperator op)
|
||||
{
|
||||
/*
|
||||
右结合,左绑定力 >= 右
|
||||
a = b = c
|
||||
a = (b = c)
|
||||
a.b.c
|
||||
*/
|
||||
switch (op)
|
||||
{
|
||||
case BinaryOperator::Assign: return GetBinaryOpLBp(op);
|
||||
case BinaryOperator::AddAssign: return GetBinaryOpLBp(op);
|
||||
case BinaryOperator::SubAssign: return GetBinaryOpLBp(op);
|
||||
case BinaryOperator::MultiplyAssign: return GetBinaryOpLBp(op);
|
||||
case BinaryOperator::DivideAssign: return GetBinaryOpLBp(op);
|
||||
case BinaryOperator::ModuloAssign: return GetBinaryOpLBp(op);
|
||||
case BinaryOperator::BitXorAssign: return GetBinaryOpLBp(op);
|
||||
case BinaryOperator::Power: return GetBinaryOpLBp(op);
|
||||
|
||||
default:
|
||||
/*
|
||||
左结合, 左绑定力 < 右
|
||||
a * b * c
|
||||
(a * b) * c
|
||||
*/
|
||||
return GetBinaryOpLBp(op) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsTokenOp(TokenType type, bool binary /* = true*/)
|
||||
{
|
||||
if (binary)
|
||||
@@ -103,4 +172,14 @@ namespace Fig
|
||||
}
|
||||
return GetUnaryOpMap().contains(type);
|
||||
}
|
||||
|
||||
UnaryOperator TokenToUnaryOp(const Token &token)
|
||||
{
|
||||
return GetUnaryOpMap().at(token.type);
|
||||
}
|
||||
BinaryOperator TokenToBinaryOp(const Token &token)
|
||||
{
|
||||
return GetBinaryOpMap().at(token.type);
|
||||
}
|
||||
|
||||
}; // namespace Fig
|
||||
@@ -35,22 +35,31 @@ namespace Fig
|
||||
Greater, // 大于 >
|
||||
LessEqual, // 小于等于 <=
|
||||
GreaterEqual, // 大于等于 >=
|
||||
|
||||
Is, // is操作符
|
||||
|
||||
Is, // is操作符
|
||||
|
||||
LogicalAnd, // 逻辑与 && / and
|
||||
LogicalOr, // 逻辑或 || / or
|
||||
|
||||
Power, // 幂运算 **
|
||||
|
||||
Assign, // 赋值(修改) =
|
||||
Assign, // 赋值(修改) =
|
||||
AddAssign, // +=
|
||||
SubAssign, // -=
|
||||
MultiplyAssign, // *=
|
||||
DivideAssign, // /=
|
||||
ModuloAssign, // %=
|
||||
BitXorAssign, // ^=
|
||||
|
||||
// 位运算
|
||||
BitAnd, // 按位与 &
|
||||
BitOr, // 按位或 |
|
||||
BitAnd, // 按位与 &
|
||||
BitOr, // 按位或 |
|
||||
BitXor, // 异或 ^
|
||||
ShiftLeft, // 左移
|
||||
ShiftRight, // 右移
|
||||
|
||||
// 成员访问
|
||||
MemberAccess, // .
|
||||
};
|
||||
|
||||
using BindingPower = unsigned int;
|
||||
@@ -61,5 +70,13 @@ namespace Fig
|
||||
HashMap<UnaryOperator, BindingPower> &GetUnaryOpBindingPowerMap();
|
||||
HashMap<BinaryOperator, BindingPower> &GetBinaryOpBindingPowerMap();
|
||||
|
||||
BindingPower GetUnaryOpRBp(UnaryOperator);
|
||||
|
||||
BindingPower GetBinaryOpLBp(BinaryOperator);
|
||||
BindingPower GetBinaryOpRBp(BinaryOperator);
|
||||
|
||||
bool IsTokenOp(TokenType type, bool binary = true);
|
||||
|
||||
UnaryOperator TokenToUnaryOp(const Token &);
|
||||
BinaryOperator TokenToBinaryOp(const Token &);
|
||||
}; // namespace Fig
|
||||
Reference in New Issue
Block a user