#include <cctype> #include <cstdio> #include <cstdlib> #include <map> #include <memory> #include <string> #include <utility> #include <vector> //===----------------------------------------------------------------------===// // Lexer //===----------------------------------------------------------------------===// // The lexer returns tokens [0-255] if it is an unknown character, otherwise one // of these for known things. enum Token { … }; static std::string IdentifierStr; // Filled in if tok_identifier static double NumVal; // Filled in if tok_number /// gettok - Return the next token from standard input. static int gettok() { … } //===----------------------------------------------------------------------===// // Abstract Syntax Tree (aka Parse Tree) //===----------------------------------------------------------------------===// namespace { /// ExprAST - Base class for all expression nodes. class ExprAST { … }; /// NumberExprAST - Expression class for numeric literals like "1.0". class NumberExprAST : public ExprAST { … }; /// VariableExprAST - Expression class for referencing a variable, like "a". class VariableExprAST : public ExprAST { … }; /// BinaryExprAST - Expression class for a binary operator. class BinaryExprAST : public ExprAST { … }; /// CallExprAST - Expression class for function calls. class CallExprAST : public ExprAST { … }; /// PrototypeAST - This class represents the "prototype" for a function, /// which captures its name, and its argument names (thus implicitly the number /// of arguments the function takes). class PrototypeAST { … }; /// FunctionAST - This class represents a function definition itself. class FunctionAST { … }; } // end anonymous namespace //===----------------------------------------------------------------------===// // Parser //===----------------------------------------------------------------------===// /// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current /// token the parser is looking at. getNextToken reads another token from the /// lexer and updates CurTok with its results. static int CurTok; static int getNextToken() { … } /// BinopPrecedence - This holds the precedence for each binary operator that is /// defined. static std::map<char, int> BinopPrecedence; /// GetTokPrecedence - Get the precedence of the pending binary operator token. static int GetTokPrecedence() { … } /// LogError* - These are little helper functions for error handling. std::unique_ptr<ExprAST> LogError(const char *Str) { … } std::unique_ptr<PrototypeAST> LogErrorP(const char *Str) { … } static std::unique_ptr<ExprAST> ParseExpression(); /// numberexpr ::= number static std::unique_ptr<ExprAST> ParseNumberExpr() { … } /// parenexpr ::= '(' expression ')' static std::unique_ptr<ExprAST> ParseParenExpr() { … } /// identifierexpr /// ::= identifier /// ::= identifier '(' expression* ')' static std::unique_ptr<ExprAST> ParseIdentifierExpr() { … } /// primary /// ::= identifierexpr /// ::= numberexpr /// ::= parenexpr static std::unique_ptr<ExprAST> ParsePrimary() { … } /// binoprhs /// ::= ('+' primary)* static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, std::unique_ptr<ExprAST> LHS) { … } /// expression /// ::= primary binoprhs /// static std::unique_ptr<ExprAST> ParseExpression() { … } /// prototype /// ::= id '(' id* ')' static std::unique_ptr<PrototypeAST> ParsePrototype() { … } /// definition ::= 'def' prototype expression static std::unique_ptr<FunctionAST> ParseDefinition() { … } /// toplevelexpr ::= expression static std::unique_ptr<FunctionAST> ParseTopLevelExpr() { … } /// external ::= 'extern' prototype static std::unique_ptr<PrototypeAST> ParseExtern() { … } //===----------------------------------------------------------------------===// // Top-Level parsing //===----------------------------------------------------------------------===// static void HandleDefinition() { … } static void HandleExtern() { … } static void HandleTopLevelExpression() { … } /// top ::= definition | external | expression | ';' static void MainLoop() { … } //===----------------------------------------------------------------------===// // Main driver code. //===----------------------------------------------------------------------===// int main() { … }