sammine-lang
Loading...
Searching...
No Matches
Parser.h
Go to the documentation of this file.
1#pragma once
2#include "ast/Ast.h"
3#include "ast/AstDecl.h"
4#include "lex/Token.h"
5#include "util/Utilities.h"
6#include <map>
7#include <memory>
8#include <optional>
9#include <utility>
12
13namespace sammine_lang {
14
19
20enum ParserError {
21 SUCCESS,
22 FAILED,
23 NONCOMMITTED,
24};
25
26template <typename T> struct ParseResult {
27 std::unique_ptr<T> node;
28 ParserError status;
29 bool ok() const { return status == SUCCESS; }
30 bool failed() const { return status == FAILED; }
31 bool uncommitted() const { return status == NONCOMMITTED; }
32};
33#define PARSER_UNREACHABLE() \
34 do { \
35 sammine_util::abort("Unreachable"); \
36 std::unreachable(); \
37 } while (0)
38#define REQUIRE(var, tokType, msg, loc, ...) \
39 auto var = expect(tokType); \
40 if (!(var)) { \
41 imm_error(msg, loc); \
42 return __VA_ARGS__; \
43 }
44using namespace AST;
45using namespace sammine_util;
46class Parser : public Reportee {
47 Location last_exhaustible_loc = Location::NonPrintable();
48 void imm_error(const std::string &msg,
49 Location loc = Location::NonPrintable(),
50 std::source_location src = std::source_location::current()) {
51 if (loc == Location::NonPrintable())
52 loc = last_exhaustible_loc;
53 if (reporter.has_value()) {
54 reporter->get().immediate_error(msg, loc, src);
55 }
56 this->error_count++;
57 }
58 void imm_diag(const std::string &msg,
59 Location loc = Location::NonPrintable(),
60 std::source_location src = std::source_location::current()) {
61 if (loc == Location::NonPrintable())
62 loc = last_exhaustible_loc;
63 if (reporter.has_value()) {
64 reporter->get().immediate_diag(msg, loc, src);
65 }
66 }
67 void imm_warn(const std::string &msg,
68 Location loc = Location::NonPrintable(),
69 std::source_location src = std::source_location::current()) {
70 if (loc == Location::NonPrintable())
71 loc = last_exhaustible_loc;
72 if (reporter.has_value()) {
73 reporter->get().immediate_warn(msg, loc, src);
74 }
75 }
76 void emit_if_uncommitted(
77 ParserError result, const std::string &msg, Location loc,
78 std::source_location src = std::source_location::current()) {
79 if (result == NONCOMMITTED)
80 imm_error(msg, loc, src);
81 }
82
83public:
84 template <class T> using p = ParseResult<T>;
85 template <class T> using u = std::unique_ptr<T>;
86 template <class T> using ListResult = std::pair<std::vector<u<T>>, ParserError>;
87
88private:
89 template <typename NodeT>
90 [[nodiscard]] auto ParseBuiltinCallExpr(TokenType keyword,
91 const std::string &name) -> p<ExprAST>;
92
93 template <typename NodeT>
94 [[nodiscard]] auto ParseUnaryPrefixExpr(TokenType opTok,
95 const std::string &opStr) -> p<ExprAST>;
96
97 template <typename T, typename... Fns>
98 auto tryParsers(Fns... fns) -> p<T> {
99 p<T> result{nullptr, NONCOMMITTED};
100 (void)((result = (this->*fns)(), result.status != NONCOMMITTED) || ...);
101 return result;
102 }
103
104public:
105 std::optional<std::reference_wrapper<Reporter>> reporter;
106 std::shared_ptr<TokenStream> tokStream;
107 std::map<std::string, std::string> alias_to_module;
108 [[nodiscard]] auto ParseImport() -> std::optional<AST::ImportDecl>;
109 [[nodiscard]] auto ParseProgram() -> u<ProgramAST>;
110
111 // Parse definition
112 [[nodiscard]] auto ParseDefinition() -> p<DefinitionAST>;
113 [[nodiscard]] auto ParsePrototype() -> p<PrototypeAST>;
114 [[nodiscard]] auto ParseFuncDef() -> p<DefinitionAST>;
115 [[nodiscard]] auto ParseVarDef() -> p<ExprAST>;
116 [[nodiscard]] auto ParseStructDef() -> p<DefinitionAST>;
117 [[nodiscard]] auto ParseEnumDef() -> p<DefinitionAST>;
118 [[nodiscard]] auto ParseTypeClassDecl() -> p<DefinitionAST>;
119 [[nodiscard]] auto ParseTypeClassInstance() -> p<DefinitionAST>;
120
121 // Parse type
122 [[nodiscard]] auto ParseTypeExprTopLevel() -> std::unique_ptr<TypeExprAST>;
123 [[nodiscard]] auto ParseTypeExpr() -> std::unique_ptr<TypeExprAST>;
124 [[nodiscard]] auto ParseTypedVar() -> p<TypedVarAST>;
125
126 // Parse expressions
127 [[nodiscard]] auto ParseExpr() -> p<ExprAST>;
128 [[nodiscard]] auto ParsePrimaryExpr() -> p<ExprAST>;
129 [[nodiscard]] auto parsePostfixOps(u<ExprAST> expr) -> p<ExprAST>;
130 [[nodiscard]] auto ParseBinaryExpr(int prededence, u<ExprAST> LHS)
131 -> p<ExprAST>;
132 [[nodiscard]] auto ParseBoolExpr() -> p<ExprAST>;
133 [[nodiscard]] auto ParseCharExpr() -> p<ExprAST>;
134
135 [[nodiscard]] auto ParseUnaryNegExpr() -> p<ExprAST>;
136 [[nodiscard]] auto ParseDerefExpr() -> p<ExprAST>;
137 [[nodiscard]] auto ParseAddrOfExpr() -> p<ExprAST>;
138 [[nodiscard]] auto ParseAllocExpr() -> p<ExprAST>;
139 [[nodiscard]] auto ParseFreeExpr() -> p<ExprAST>;
140 [[nodiscard]] auto ParseLenExpr() -> p<ExprAST>;
141 [[nodiscard]] auto ParseArrayLiteralExpr() -> p<ExprAST>;
142 [[nodiscard]] auto ParseCallExpr() -> p<ExprAST>;
143 [[nodiscard]] auto ParseStructLiteralExpr(sammine_util::QualifiedName qn,
144 Location qn_loc) -> p<ExprAST>;
145 [[nodiscard]] auto ParseReturnExpr() -> p<ExprAST>;
146 [[nodiscard]] auto ParseArguments() -> ListResult<ExprAST>;
147 [[nodiscard]] auto ParseParenExpr() -> p<ExprAST>;
148 [[nodiscard]] auto ParseIfExpr() -> p<ExprAST>;
149 [[nodiscard]] auto ParseCaseExpr() -> p<ExprAST>;
150 [[nodiscard]] auto ParseWhileExpr() -> p<ExprAST>;
151 [[nodiscard]] auto ParseNumberExpr() -> p<ExprAST>;
152 [[nodiscard]] auto ParseStringExpr() -> p<ExprAST>;
153 [[nodiscard]] auto ParseVariableExpr() -> p<ExprAST>;
154
155 // Parse block
156 [[nodiscard]] auto ParseBlock() -> p<BlockAST>;
157
158 // Parse parameters
159 [[nodiscard]] auto ParseParams() -> ListResult<TypedVarAST>;
160
161 // Utilities
162 [[nodiscard]] auto expect(TokenType tokType, bool exhausts = false,
163 TokenType until = TokenType::TokEOF,
164 const std::string &message = "")
165 -> std::shared_ptr<Token>;
166
170 [[nodiscard]] auto parseQualifiedNameTail(std::shared_ptr<Token> first_tok,
171 bool resolve_alias = true)
173
177 [[nodiscard]] auto
180 -> std::vector<std::unique_ptr<TypeExprAST>>;
181
182 [[nodiscard]] auto consumeClosingAngleBracket() -> bool;
183
184 bool parsed_var_arg = false;
185 int pending_deref = 0;
186 std::shared_ptr<Token> pending_deref_tok;
187
188 [[nodiscard]] Parser(
189 std::optional<std::reference_wrapper<Reporter>> reporter = std::nullopt, const std::string &default_namespace = "")
190 : reporter(reporter) {}
191 [[nodiscard]] Parser(
192 std::shared_ptr<TokenStream> tokStream,
193 std::optional<std::reference_wrapper<Reporter>> reporter = std::nullopt, const std::string &default_namespace = "")
194 : reporter(reporter), tokStream(tokStream) {}
195
196 [[nodiscard]] auto Parse() -> u<ProgramAST>;
197};
198} // namespace sammine_lang
Holds declaration for all the AST Nodes.
Defined the AST Node classes (ProgramAST, StructDefAST, FuncDefAST) and a visitor interface for trave...
Defines the token structure (TokenType, TokStream, TokenMap).
Holds classes and functionalities for dealing with Error handling, source locations caching & indexin...
auto parseQualifiedNameTail(std::shared_ptr< Token > first_tok, bool resolve_alias=true) -> ParsedQualifiedName
Definition Parser.cpp:1828
auto ParseVarDef() -> p< ExprAST >
Parsing implementation for a variable decl/def.
Definition Parser.cpp:446
auto parseExplicitTypeArgsTail(sammine_util::QualifiedName &qn, sammine_util::Location &qn_loc) -> std::vector< std::unique_ptr< TypeExprAST > >
Definition Parser.cpp:1865
Definition Utilities.h:70
Definition Utilities.h:130
Definition Parser.h:26
Definition Parser.h:15
Definition QualifiedName.h:23