This commit is contained in:
Zengtudor 2025-07-19 21:34:50 +08:00
parent 0d4f840154
commit 7de5b48089
2 changed files with 93 additions and 5 deletions

View File

@ -3,8 +3,16 @@
#include "Lexer.hpp"
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <format>
#include <list>
#include <memory>
#include <sstream>
#include <stdexcept>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>
#include <variant>
#include <vector>
@ -19,8 +27,7 @@ namespace ztl{
};
struct BinaryExpression{
enum OperatorType{
One,
Add
Add,
};
OperatorType Operator;
using LRType = std::variant<
@ -30,6 +37,16 @@ namespace ztl{
LRType left;
LRType right;
};
struct UnaryExpression{
enum struct Operator{
Not='!',
Minus='-'
}op;
std::variant<Identifier,Literal> right;
};
struct Expression{
std::variant<BinaryExpression,Identifier,UnaryExpression> son;
};
struct VariableDeclaration{
Identifier id;
BinaryExpression init;
@ -38,9 +55,80 @@ namespace ztl{
using BodyType = std::vector<std::variant<VariableDeclaration>>;
BodyType body;
};
AST(const std::vector<Token> &tokens){
auto getExpr(std::vector<Token> &tokens,int64_t begin,int64_t end)->std::tuple<VariableDeclaration,int64_t>{
std::list<std::variant<Token,BinaryExpression,UnaryExpression,Literal,Identifier>> l(tokens.begin()+begin,tokens.begin()+end);
for (auto it = l.begin();it!=l.end();it++) { // 转化字面量和变量名
if(std::holds_alternative<Token>(*it)){
if(std::get<Token>(*it).type==ztl::TokenType::Identifier){
(*it)=Identifier{
.name = std::get<Token>(*it).str
};
}else if(std::get<Token>(*it).type==ztl::TokenType::Literal){
(*it)=Literal{
.value = atoi(std::get<Token>(*it).str.data())
};
}else if(std::get<Token>(*it).type==ztl::TokenType::Operator){
continue;
}else{
std::runtime_error("only Identifier Literal Operator can be put into a Expr");
}
}else{
std::runtime_error("unknown type when AST");
}
}
for(auto it = l.begin();it!=l.end();it++){ // 一元表达式
if(!(std::holds_alternative<Token>(*it)))continue;
auto nit = it;
nit++;
if(!(nit!=l.end()&&(std::holds_alternative<Literal>(*nit)||std::holds_alternative<Identifier>(*nit))))throw std::runtime_error(std::format("no char after char '{}' when AST or no value after it",std::get<Token>(*it).str));
std::variant<Identifier,Literal> right;
right = std::visit([](auto &i){
using T = std::decay_t<decltype(i)> ;
if constexpr(std::is_same_v<Literal, T>||std::is_same_v<Identifier, T>){
return std::variant<Identifier, Literal>(i);
}else{
throw std::runtime_error("cannot get type when AST");
}
std::unreachable();
return std::variant<Identifier, Literal>();
},
*nit);
l.erase(nit);
if(std::get<Token>(*it).str=="-"){
(*it) = UnaryExpression{
.op = UnaryExpression::Operator::Minus,
.right = right
};
continue;
}else if(std::get<Token>(*it).str=="!"){
(*it) = UnaryExpression{
.op = UnaryExpression::Operator::Not,
.right = right
};
continue;
}
else{
throw std::runtime_error(std::format("unknown UnaryExpression char '{}'",std::get<Token>(*it).str));
}
}
for(auto it = l.begin();it!=l.end();it++){ //二元表达式*
if(std::holds_alternative<UnaryExpression>(*it)||std::holds_alternative<Literal>(*it)||std::holds_alternative<Identifier>(*it)){
auto nit = it;
nit++;
if(nit!=l.end()&&std::holds_alternative<Token>(*nit)&&(std::get<Token>(*nit).str=="*"||std::get<Token>(*nit).str=="/"))
}else{
throw std::runtime_error("cannot get type when AST");
}
}
}
AST(std::vector<Token> tokens){
for(size_t i=0;i<tokens.size();i++){
if(tokens[i].str=="int"){
}else{
throw std::runtime_error(std::format("unknown token '{}' when AST",tokens[i].str));
}
}
}
};

View File

@ -39,7 +39,7 @@ namespace ztl{
ZTL_FOR_EACH_V(Whitespace)\
#define ZTL_FOR_EACH_V(v)v,
enum class TokenType{
enum struct TokenType{
ZTL_FOR_EACH
};
#undef ZTL_FOR_EACH_V