/// gettok - Return the next token from standard input.staticintgettok(){staticintLastChar=' ';// Skip any whitespace.while(isspace(LastChar))LastChar=getchar();if(isalpha(LastChar)){// identifier: [a-zA-Z][a-zA-Z0-9]*IdentifierStr=LastChar;while(isalnum((LastChar=getchar())))IdentifierStr+=LastChar;if(IdentifierStr=="def")returntok_def;if(IdentifierStr=="extern")returntok_extern;returntok_identifier;}if(isdigit(LastChar)||LastChar=='.'){// Number: [0-9.]+std::stringNumStr;do{NumStr+=LastChar;LastChar=getchar();}while(isdigit(LastChar)||LastChar=='.');NumVal=strtod(NumStr.c_str(),nullptr);returntok_number;}if(LastChar=='#'){// Comment until end of line.doLastChar=getchar();while(LastChar!=EOF&&LastChar!='\n'&&LastChar!='\r');if(LastChar!=EOF)returngettok();}}
publicenumTokenType{// Dynamic token, need be interpreted by parserDYNAMIC,EOF,// Code commentCOMMENT,// Define sharedVariableDEF_VARIABLE,// Define nodeDEF_NODE,// Value typeVALUE}/// <summary>/// Each token returned by the lexer includes a token type and potentially a string value/// </summary>publicreadonlystructToken{publicTokenTypeType{get;}publicstringValue{get;}publicToken(TokenTypetokenType){Type=tokenType;Value=default;}publicToken(stringvalue){Type=TokenType.DYNAMIC;Value=value;}publicToken(TokenTypetokenType,stringvalue){Type=tokenType;Value=value;}publicstaticbooloperator==(Tokenfirst,Tokensecond){returnfirst.Type==second.Type&&first.Value==second.Value;}publicstaticbooloperator!=(Tokenfirst,Tokensecond){returnfirst.Type!=second.Type||first.Value!=second.Value;}publicstaticbooloperator==(Tokenfirst,TokenTypesecond){returnfirst.Type==second;}publicstaticbooloperator!=(Tokenfirst,TokenTypesecond){returnfirst.Type!=second;}publicstaticbooloperator==(Tokenfirst,stringsecond){returnfirst.Value==second;}publicstaticbooloperator!=(Tokenfirst,stringsecond){returnfirst.Value!=second;}publicboolEquals(Tokenother){returnother.Type==Type&&other.Value==Value;}publicoverrideboolEquals(objectobj){returnobjisTokentoken&&Equals(token);}publicoverrideintGetHashCode(){returnHashCode.Combine(Type,Value);}publicoverridestringToString(){return$"[{Type}]{Value}";}}
// Kaleidoscope的AST节点// 引用自 https://llvm-tutorial-cn.readthedocs.io/en/latest/chapter-2.html/// VariableExprAST - Expression class for referencing a variable, like "a".classVariableExprAST:publicExprAST{std::stringName;public:VariableExprAST(conststd::string&name):Name(name){}};/// BinaryExprAST - Expression class for a binary operator.classBinaryExprAST:publicExprAST{charOp;ExprAST*LHS,*RHS;public:BinaryExprAST(charop,ExprAST*lhs,ExprAST*rhs):Op(op),LHS(lhs),RHS(rhs){}};/// CallExprAST - Expression class for function calls.classCallExprAST:publicExprAST{std::stringCallee;std::vector<ExprAST*>Args;public:CallExprAST(conststd::string&callee,std::vector<ExprAST*>&args):Callee(callee),Args(args){}};