update
This commit is contained in:
parent
0d4f840154
commit
7de5b48089
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user