Parser.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. #include "Parser.h"
  2. using namespace lexer;
  3. namespace parser{
  4. //===----------------------------------------------------------------------===//
  5. // Parser
  6. //===----------------------------------------------------------------------===//
  7. /// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current
  8. /// token the parser is looking at. getNextToken reads another token from the
  9. /// lexer and updates CurTok with its results.
  10. int getNextToken() { return CurTok = gettok(); }
  11. /// BinopPrecedence - This holds the precedence for each binary operator that is
  12. /// defined.
  13. /// GetTokPrecedence - Get the precedence of the pending binary operator token.
  14. static int GetTokPrecedence() {
  15. if (!isascii(CurTok))
  16. return -1;
  17. // Make sure it's a declared binop.
  18. int TokPrec = BinopPrecedence[CurTok];
  19. if (TokPrec <= 0)
  20. return -1;
  21. return TokPrec;
  22. }
  23. /// Error* - These are little helper functions for error handling.
  24. std::unique_ptr<ExprAST> Error(const char *Str) {
  25. fprintf(stderr, "Error: %s\n", Str);
  26. return nullptr;
  27. }
  28. std::unique_ptr<PrototypeAST> ErrorP(const char *Str) {
  29. Error(Str);
  30. return nullptr;
  31. }
  32. static std::unique_ptr<ExprAST> ParseExpression();
  33. /// numberexpr ::= number
  34. static std::unique_ptr<ExprAST> ParseNumberExpr() {
  35. auto Result = llvm::make_unique<NumberExprAST>(LexerObjects::NumVal);
  36. getNextToken(); // consume the number
  37. return std::move(Result);
  38. }
  39. /// parenexpr ::= '(' expression ')'
  40. static std::unique_ptr<ExprAST> ParseParenExpr() {
  41. getNextToken(); // eat (.
  42. auto V = ParseExpression();
  43. if (!V)
  44. return nullptr;
  45. if (CurTok != ')')
  46. return Error("expected ')'");
  47. getNextToken(); // eat ).
  48. return V;
  49. }
  50. /// identifierexpr
  51. /// ::= identifier
  52. /// ::= identifier '(' expression* ')'
  53. static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
  54. std::string IdName = LexerObjects::IdentifierStr;
  55. getNextToken(); // eat identifier.
  56. if (CurTok != '(') // Simple variable ref.
  57. return llvm::make_unique<VariableExprAST>(IdName);
  58. // Call.
  59. getNextToken(); // eat (
  60. std::vector<std::unique_ptr<ExprAST>> Args;
  61. if (CurTok != ')') {
  62. while (1) {
  63. if (auto Arg = ParseExpression())
  64. Args.push_back(std::move(Arg));
  65. else
  66. return nullptr;
  67. if (CurTok == ')')
  68. break;
  69. if (CurTok != ',')
  70. return Error("Expected ')' or ',' in argument list");
  71. getNextToken();
  72. }
  73. }
  74. // Eat the ')'.
  75. getNextToken();
  76. return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
  77. }
  78. /// primary
  79. /// ::= identifierexpr
  80. /// ::= numberexpr
  81. /// ::= parenexpr
  82. static std::unique_ptr<ExprAST> ParsePrimary() {
  83. switch (CurTok) {
  84. default:
  85. return Error("unknown token when expecting an expression");
  86. case tok_identifier:
  87. return ParseIdentifierExpr();
  88. case tok_number:
  89. return ParseNumberExpr();
  90. case '(':
  91. return ParseParenExpr();
  92. }
  93. }
  94. /// binoprhs
  95. /// ::= ('+' primary)*
  96. static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
  97. std::unique_ptr<ExprAST> LHS) {
  98. // If this is a binop, find its precedence.
  99. while (1) {
  100. int TokPrec = GetTokPrecedence();
  101. // If this is a binop that binds at least as tightly as the current binop,
  102. // consume it, otherwise we are done.
  103. if (TokPrec < ExprPrec)
  104. return LHS;
  105. // Okay, we know this is a binop.
  106. int BinOp = CurTok;
  107. getNextToken(); // eat binop
  108. // Parse the primary expression after the binary operator.
  109. auto RHS = ParsePrimary();
  110. if (!RHS)
  111. return nullptr;
  112. // If BinOp binds less tightly with RHS than the operator after RHS, let
  113. // the pending operator take RHS as its LHS.
  114. int NextPrec = GetTokPrecedence();
  115. if (TokPrec < NextPrec) {
  116. RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS));
  117. if (!RHS)
  118. return nullptr;
  119. }
  120. // Merge LHS/RHS.
  121. LHS =
  122. llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
  123. }
  124. }
  125. /// expression
  126. /// ::= primary binoprhs
  127. ///
  128. static std::unique_ptr<ExprAST> ParseExpression() {
  129. auto LHS = ParsePrimary();
  130. if (!LHS)
  131. return nullptr;
  132. return ParseBinOpRHS(0, std::move(LHS));
  133. }
  134. /// prototype
  135. /// ::= id '(' id* ')'
  136. static std::unique_ptr<PrototypeAST> ParsePrototype() {
  137. if (CurTok != tok_identifier)
  138. return ErrorP("Expected function name in prototype");
  139. std::string FnName = LexerObjects::IdentifierStr;
  140. getNextToken();
  141. if (CurTok != '(')
  142. return ErrorP("Expected '(' in prototype");
  143. std::vector<std::string> ArgNames;
  144. while (getNextToken() == tok_identifier)
  145. ArgNames.push_back(LexerObjects::IdentifierStr);
  146. if (CurTok != ')')
  147. return ErrorP("Expected ')' in prototype");
  148. // success.
  149. getNextToken(); // eat ')'.
  150. return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames));
  151. }
  152. /// definition ::= 'def' prototype expression
  153. static std::unique_ptr<FunctionAST> ParseDefinition() {
  154. getNextToken(); // eat def.
  155. auto Proto = ParsePrototype();
  156. if (!Proto)
  157. return nullptr;
  158. if (auto E = ParseExpression())
  159. return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
  160. return nullptr;
  161. }
  162. /// toplevelexpr ::= expression
  163. static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
  164. if (auto E = ParseExpression()) {
  165. // Make an anonymous proto.
  166. auto Proto = llvm::make_unique<PrototypeAST>("__anon_expr", std::vector<std::string>());
  167. return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
  168. }
  169. return nullptr;
  170. }
  171. /// external ::= 'extern' prototype
  172. static std::unique_ptr<PrototypeAST> ParseExtern() {
  173. getNextToken(); // eat extern.
  174. return ParsePrototype();
  175. }
  176. //===----------------------------------------------------------------------===//
  177. // Top-Level parsing and JIT Driver
  178. //===----------------------------------------------------------------------===//
  179. static void HandleDefinition() {
  180. if (auto FnAST = ParseDefinition()) {
  181. if (auto *FnIR = FnAST->codegen()) {
  182. fprintf(stderr, "Read function definition:");
  183. FnIR->dump();
  184. }
  185. } else {
  186. // Skip token for error recovery.
  187. getNextToken();
  188. }
  189. }
  190. static void HandleExtern() {
  191. if (auto ProtoAST = ParseExtern()) {
  192. if (auto *FnIR = ProtoAST->codegen()) {
  193. fprintf(stderr, "Read extern: ");
  194. FnIR->dump();
  195. }
  196. } else {
  197. // Skip token for error recovery.
  198. getNextToken();
  199. }
  200. }
  201. static void HandleTopLevelExpression() {
  202. // Evaluate a top-level expression into an anonymous function.
  203. if (auto FnAST = ParseTopLevelExpr()) {
  204. if (auto *FnIR = FnAST->codegen()) {
  205. fprintf(stderr, "Read top-level expression:");
  206. FnIR->dump();
  207. }
  208. } else {
  209. // Skip token for error recovery.
  210. getNextToken();
  211. }
  212. }
  213. /// top ::= definition | external | expression | ';'
  214. void MainLoop() {
  215. // Install standard binary operators.
  216. // 1 is lowest precedence.
  217. BinopPrecedence['<'] = 10;
  218. BinopPrecedence['+'] = 20;
  219. BinopPrecedence['-'] = 20;
  220. BinopPrecedence['*'] = 40; // highest.
  221. while (1) {
  222. fprintf(stderr, "ready> ");
  223. switch (CurTok) {
  224. case tok_eof:
  225. return;
  226. case ';': // ignore top-level semicolons.
  227. getNextToken();
  228. break;
  229. case tok_def:
  230. HandleDefinition();
  231. break;
  232. case tok_extern:
  233. HandleExtern();
  234. break;
  235. default:
  236. HandleTopLevelExpression();
  237. break;
  238. }
  239. }
  240. }
  241. }