update
This commit is contained in:
parent
0d4f840154
commit
7de5b48089
@ -3,8 +3,16 @@
|
|||||||
#include "Lexer.hpp"
|
#include "Lexer.hpp"
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <format>
|
||||||
|
#include <list>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <sstream>
|
||||||
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -19,8 +27,7 @@ namespace ztl{
|
|||||||
};
|
};
|
||||||
struct BinaryExpression{
|
struct BinaryExpression{
|
||||||
enum OperatorType{
|
enum OperatorType{
|
||||||
One,
|
Add,
|
||||||
Add
|
|
||||||
};
|
};
|
||||||
OperatorType Operator;
|
OperatorType Operator;
|
||||||
using LRType = std::variant<
|
using LRType = std::variant<
|
||||||
@ -30,6 +37,16 @@ namespace ztl{
|
|||||||
LRType left;
|
LRType left;
|
||||||
LRType right;
|
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{
|
struct VariableDeclaration{
|
||||||
Identifier id;
|
Identifier id;
|
||||||
BinaryExpression init;
|
BinaryExpression init;
|
||||||
@ -38,9 +55,80 @@ namespace ztl{
|
|||||||
using BodyType = std::vector<std::variant<VariableDeclaration>>;
|
using BodyType = std::vector<std::variant<VariableDeclaration>>;
|
||||||
BodyType body;
|
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++){
|
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)\
|
ZTL_FOR_EACH_V(Whitespace)\
|
||||||
|
|
||||||
#define ZTL_FOR_EACH_V(v)v,
|
#define ZTL_FOR_EACH_V(v)v,
|
||||||
enum class TokenType{
|
enum struct TokenType{
|
||||||
ZTL_FOR_EACH
|
ZTL_FOR_EACH
|
||||||
};
|
};
|
||||||
#undef ZTL_FOR_EACH_V
|
#undef ZTL_FOR_EACH_V
|
||||||
|
Loading…
Reference in New Issue
Block a user