/*! @file src/Parser/Parser.hpp @brief 语法分析器(Pratt + 手动递归下降) 定义 @author PuqiAR (im@puqiar.top) @date 2026-02-14 */ #pragma once #include #include #include #include #include #include #include #include namespace Fig { class Parser { private: Lexer &lexer; SourceManager &srcManager; size_t index = 0; // token在buffer下标 DynArray buffer; String fileName; bool isEOF = false; Token nextToken() { assert(!isEOF && "nextToken: eof but called nextToken"); if (index + 1 < buffer.size()) { return buffer[++index]; } const auto &result = lexer.NextToken(); if (!result) { ReportError(result.error(), srcManager); std::exit(-1); } const Token &token = result.value(); if (token.type == TokenType::EndOfFile) { isEOF = true; } buffer.push_back(token); index++; return token; } inline Token prevToken() { if (buffer.size() < 2) { return currentToken(); } return buffer[buffer.size() - 2]; } inline Token currentToken() { if (buffer.empty()) { return nextToken(); } return buffer.back(); } Token peekToken(size_t lookahead = 1) { assert(!isEOF && "peekToken: eof but called peekToken"); size_t peekIndex = index + lookahead; while (peekIndex >= buffer.size() && !isEOF) { const auto &result = lexer.NextToken(); if (!result) { ReportError(result.error(), srcManager); std::abort(); } const Token &token = result.value(); if (token.type == TokenType::EndOfFile) { isEOF = true; } buffer.push_back(token); } if (peekIndex >= buffer.size()) // 没有那么多token { return buffer.back(); // back是EOF Token } return buffer[peekIndex]; } inline Token consumeToken() { if (isEOF) return buffer.back(); Token current = currentToken(); nextToken(); return current; } public: enum class State : std::uint8_t { Standby, ParsingLiteralExpr, ParsingIdentiExpr, ParsingInfixExpr, ParsingPrefixExpr, ParsingIndexExpr, ParsingCallExpr, } state; Parser(Lexer &_lexer, SourceManager &_srcManager, String _fileName) : lexer(_lexer), srcManager(_srcManager), fileName(std::move(_fileName)) { state = State::Standby; } private: SourceLocation makeSourcelocation(const Token &tok) { auto [line, column] = srcManager.GetLineColumn(tok.index); return SourceLocation( SourcePosition( line, column, tok.length ), fileName, "[internal parser]", magic_enum::enum_name(state).data()); } /* Expressions */ Result parseLiteralExpr(); // 当前token为literal时调用 Result parseIdentiExpr(); // 当前token为Identifier调用 Result parseInfixExpr(Expr *); // 由 parseExpression递归调用, 当前token为op Result parsePrefixExpr(); // 由 parseExpression递归调用, 当前token为op Result parseIndexExpr(Expr *); // 由 parseExpression调用, 当前token为 `[` Result parseCallExpr(Expr *); // 由 parseExpression调用, 当前token为 `(` std::unordered_set getTerminators(); // 返回固定的终止符 bool shouldTerminate(); // 判断是否终结 // Result parseExpression(BindingPower = 0); /* Statements */ public: Result parseExpression(BindingPower = 0); DynArray parseAll(); }; }; // namespace Fig