MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
parser.h
Go to the documentation of this file.
1#pragma once
2
3#include <fe/parser.h>
4
5#include "mim/ast/ast.h"
6#include "mim/ast/lexer.h"
7
8namespace mim::ast {
9
10constexpr size_t Look_Ahead = 2;
11
12/// Parses Mim code as AST.
13///
14/// The logic behind the various parse methods is as follows:
15/// 1. The `parse_*` method does **not** have a `std::string_view ctxt` parameter:
16///
17/// It's the **caller's responsibility** to first make appropriate
18/// [FIRST/FOLLOW](https://www.cs.uaf.edu/~cs331/notes/FirstFollow.pdf) checks.
19/// Otherwise, an assertion will be triggered in the case of a syntax error.
20///
21/// 2. The `parse_*` method does have a `std::string_view ctxt` parameter:
22///
23/// The **called method** checks this and spits out an appropriate error message using `ctxt` in the case of a
24/// syntax error.
25///
26/// 3. The `parse_*` method does have a `std::string_view ctxt = {}` parameter **with default argument**:
27///
28/// * If default argument is **elided** we have the same behavior as in 1.
29/// * If default argument is **provided** we have the same behavior as in 2.
30class Parser : public fe::Parser<Tok, Tok::Tag, Look_Ahead, Parser> {
31 using Super = fe::Parser<Tok, Tok::Tag, Look_Ahead, Parser>;
32
33public:
35 : ast_(ast) {}
36
37 AST& ast() { return ast_; }
38 Driver& driver() { return ast().driver(); }
39 Ptr<Module> import(std::string_view sv) { return import({Loc(), driver().sym(sv)}); }
40 Ptr<Module> import(Dbg, std::ostream* md = nullptr);
41 Ptr<Module> import(std::istream&, Loc = {}, const fs::path* = nullptr, std::ostream* md = nullptr);
43 Ptr<Module> plugin(const std::string& s) { return plugin({Loc(), driver().sym(s)}); }
44 Ptr<Module> plugin(const char* name) { return plugin({Loc(), driver().sym(name)}); }
45
46private:
47 template<class T, class... Args> auto ptr(Args&&... args) {
48 return ast_.ptr<const T>(std::forward<Args&&>(args)...);
49 }
50
51 Dbg anon() const { return {ahead().loc().anew_begin(), ast_.sym_anon()}; }
52 Dbg dbg(const Tracker& tracker, Sym sym) const { return {tracker.loc(), sym}; }
53 Lexer& lexer() { return *lexer_; }
54
55 /// @name parse misc
56 ///@{
57 Ptr<Module> parse_module();
58 Dbg parse_id(std::string_view ctxt = {});
59 std::pair<Annex&, bool> parse_annex(std::string_view ctxt = {});
60 Dbg parse_name(std::string_view ctxt = {});
61 Ptr<Import> parse_import_or_plugin();
62 Ptr<Import> parse_plugin();
63 Ptr<Expr> parse_type_ascr(std::string_view ctxt = {});
64
65 template<class F> void parse_list(std::string ctxt, Tok::Tag delim_l, F f, Tok::Tag sep = Tok::Tag::T_comma) {
66 expect(delim_l, ctxt);
67 auto delim_r = Tok::delim_l2r(delim_l);
68 if (!ahead().isa(delim_r)) {
69 do { f(); } while (accept(sep) && !ahead().isa(delim_r));
70 }
71 expect(delim_r, std::string("closing delimiter of a ") + ctxt);
72 }
73 ///@}
74
75 /// @name parse exprs
76 ///@{
77 Ptr<Expr> parse_expr(std::string_view ctxt, Prec = Prec::Bot);
78 Ptr<Expr> parse_primary_expr(std::string_view ctxt);
79 Ptr<Expr> parse_infix_expr(Tracker, Ptr<Expr>&& lhs, Prec = Prec::Bot);
80 ///@}
81
82 /// @name parse primary exprs
83 ///@{
84 template<bool> Ptr<Expr> parse_arr_or_pack_expr();
85 Ptr<Expr> parse_decl_expr();
86 Ptr<Expr> parse_lit_expr();
87 Ptr<Expr> parse_extremum_expr();
88 Ptr<Expr> parse_type_expr();
89 Ptr<Expr> parse_ret_expr();
90 Ptr<Expr> parse_pi_expr(Ptr<Ptrn>&& = nullptr);
91 Ptr<Expr> parse_lam_expr();
92 Ptr<Expr> parse_sigma_expr();
93 Ptr<Expr> parse_tuple_expr();
94 Ptr<Expr> parse_insert_expr();
95 ///@}
96
97 /// @name parse ptrns
98 ///@{
99 /// Depending on @p tag, this parses a `()`-style (Tok::Tag::D_paren_l) or `[]`-style (Tok::Tag::D_brckt_l) Ptrn.
100 Ptr<Ptrn> parse_ptrn(Tok::Tag tag, std::string_view ctxt, Prec = Prec::Bot, bool allow_annex = false);
101 Ptr<TuplePtrn> parse_tuple_ptrn();
102 ///@}
103
104 /// @name parse decls
105 ///@{
106 /// If @p ctxt ...
107 /// * ... empty: **Only** decls are parsed. @returns `nullptr`
108 /// * ... **non**-empty: Decls are parsed, then an expression. @returns expression.
109 Ptrs<ValDecl> parse_decls();
110 Ptr<ValDecl> parse_axiom_decl();
111 Ptr<ValDecl> parse_let_decl();
112 Ptr<ValDecl> parse_c_decl();
113 Ptr<LamDecl> parse_lam_decl();
114 Ptr<RecDecl> parse_rec_decl(bool first);
115 Ptr<RecDecl> parse_and_decl();
116 ///@}
117
118 /// @name error messages
119 ///@{
120 /// Issue an error message of the form:
121 /// "expected <what>, got '<tok>\' while parsing <ctxt>"
122 void syntax_err(std::string_view what, const Tok& tok, std::string_view ctxt) {
123 ast().error(tok.loc(), "expected {}, got '{}' while parsing {}", what, tok, ctxt);
124 }
125
126 /// Same above but uses @p ahead() as @p tok.
127 void syntax_err(std::string_view what, std::string_view ctxt) { syntax_err(what, ahead(), ctxt); }
128
129 void syntax_err(Tok::Tag tag, std::string_view ctxt) {
130 std::string msg("'");
131 msg.append(Tok::tag2str(tag)).append("'");
132 syntax_err(msg, ctxt);
133 }
134
135 using Super::expect;
136 template<class... Args> Tok expect(Tok::Tag tag, const char* f, Args&&... args) {
137 std::ostringstream oss;
138 print(oss, f, std::forward<Args&&>(args)...);
139 return Super::expect(tag, oss.str());
140 }
141 ///@}
142
143 AST& ast_;
144 Lexer* lexer_ = nullptr;
145
146 friend Super;
147};
148
149} // namespace mim::ast
Some "global" variables needed all over the place.
Definition driver.h:17
Driver & driver()
Definition ast.h:62
auto ptr(Args &&... args)
Definition ast.h:77
Sym sym_anon()
"_".
Definition ast.h:72
Error & error()
Definition ast.h:63
Parses Mim code as AST.
Definition parser.h:30
Parser(AST &ast)
Definition parser.h:34
AST & ast()
Definition parser.h:37
Ptr< Module > plugin(const std::string &s)
Definition parser.h:43
Ptr< Module > plugin(const char *name)
Definition parser.h:44
Driver & driver()
Definition parser.h:38
Ptr< Module > plugin(Dbg)
Definition parser.cpp:156
static constexpr Tok::Tag delim_l2r(Tag tag)
Definition tok.h:132
static const char * tag2str(Tok::Tag)
Definition tok.cpp:10
Definition ast.h:14
fe::Arena::Ptr< const T > Ptr
Definition ast.h:21
constexpr size_t Look_Ahead
Definition parser.h:10
std::deque< Ptr< T > > Ptrs
Definition ast.h:22
std::ostream & print(std::ostream &os, const char *s)
Base case.
Definition print.cpp:5