MimIR
0.5-dev
MimIR is my Intermediate Representation
Toggle main menu visibility
Loading...
Searching...
No Matches
lexer.h
Go to the documentation of this file.
1
#pragma once
2
3
#include <string>
4
5
#include <fe/lexer.h>
6
7
#include "
mim/driver.h
"
8
9
#include "
mim/ast/tok.h
"
10
11
namespace
mim::ast
{
12
13
class
Lexer
:
public
fe::Lexer<3, Lexer> {
14
using
Super = fe::Lexer<3, Lexer>;
15
16
public
:
17
/// Creates a lexer to read `*.mim` files (see [Lexical Structure](@ref lex)).
18
/// If @p md is not `nullptr`, a Markdown output will be generated.
19
Lexer
(
Driver
&
driver
,
const
fe::Src& src, std::ostream* md =
nullptr
)
20
:
Lexer
(
driver
, src.buf(), &src, md) {}
21
/// As above, but the Loc%ations of the Tok%s produced have no fe::Src to resolve against.
22
Lexer
(
Driver
&
driver
, std::string_view buf, std::ostream* md =
nullptr
)
23
:
Lexer
(
driver
, buf, nullptr, md) {}
24
25
Driver
&
driver
() {
return
driver_; }
///< fe::Lexer's default diagnostics go to its Driver::error.
26
Tok
lex
();
27
28
/// Does @p str match the `id` production - the same rule Lexer::lex_id applies to the input?
29
static
bool
is_id
(std::string_view str);
30
31
/// Inverse of Lexer::lex_char: renders @p str as the body of a Mim string literal.
32
static
std::string
escape
(std::string_view str);
33
34
private
:
35
Lexer
(
Driver
&, std::string_view,
const
fe::Src*, std::ostream*);
36
37
Tok
tok(
Tok::Tag
tag) {
return
{loc_, tag}; }
38
Sym sym() {
return
driver
().sym(view()); }
39
bool
lex_id();
40
char8_t
lex_char();
41
Tok lex_str();
42
Tok lex_lit();
43
void
lex_digits(
int
base = 10);
44
bool
lex_exp(
int
base = 10);
45
f64
lex_f64(std::string_view,
int
base);
46
void
eat_comments();
47
48
/// Interns the string literal occupying `[begin, end)` of Lexer::buf_; @p esc resolves its escapes first.
49
Sym sym_str(uint32_t begin, uint32_t end,
bool
esc);
50
/// Resolves the escapes of @p body, which starts at byte @p begin of Lexer::buf_.
51
std::string unquote(std::string_view body, uint32_t begin);
52
53
/// @name Markdown
54
/// Whatever is consumed lands in Lexer::md_ verbatim, wrapped in a `mim` code fence.
55
/// A `///` line interrupts that fence and goes through as Markdown, its marker skipped.
56
///@{
57
bool
start_md()
const
{
return
ahead(0) ==
'/'
&& ahead(1) ==
'/'
&& ahead(2) ==
'/'
; }
58
void
emit_md(
bool
start_of_file =
false
);
59
size_t
pos()
const
{
return
peek().begin.off; }
///< First byte not yet consumed.
60
/// Writes @p str to Lexer::md_ while tracking the newlines the output ends with.
61
/// Outside a fence a run of empty lines collapses into one, as a Markdown linter wants.
62
void
md_emit(std::string_view str) {
63
if
(!md_)
return
;
64
for
(
auto
c : str) {
65
if
(c ==
'\n'
&& !fenced_ && md_nls_ >= 2)
continue
;
66
*md_ <<
c
;
67
md_nls_ =
c
==
'\n'
? md_nls_ + 1 : 0;
68
}
69
}
70
void
md_blank() { md_emit(
"\n\n"
); }
///< Makes the output end with an empty line, as a fence needs on either side.
71
void
md_flush() {
72
md_emit(buf_.substr(md_pos_, pos() - md_pos_));
73
md_pos_ = pos();
74
}
75
void
md_skip() { md_pos_ = pos(); }
76
/// The language tag switches on Mim syntax highlighting in the generated documentation.
77
void
md_open() {
78
md_blank();
79
md_emit(
"```mim\n"
);
80
fenced_ = md_ !=
nullptr
;
81
}
82
void
md_close() {
83
md_emit(
"```\n"
);
84
fenced_ =
false
;
85
}
86
///@}
87
88
Driver& driver_;
89
std::ostream* md_;
90
size_t
md_pos_ = 0;
91
size_t
md_nls_ = 2;
///< Newlines the Markdown output ends with; starts at 2, so it never begins with an empty line.
92
bool
fenced_ =
false
;
///< Is a code fence currently open?
93
94
friend
class
fe::Lexer<3,
Lexer
>;
95
};
96
97
}
// namespace mim::ast
mim::Driver
Some "global" variables needed all over the place.
Definition
driver.h:64
mim::ast::Lexer::driver
Driver & driver()
fe::Lexer's default diagnostics go to its Driver::error.
Definition
lexer.h:25
mim::ast::Lexer::is_id
static bool is_id(std::string_view str)
Does str match the id production - the same rule Lexer::lex_id applies to the input?
Definition
lexer.cpp:261
mim::ast::Lexer::lex
Tok lex()
Definition
lexer.cpp:76
mim::ast::Lexer::escape
static std::string escape(std::string_view str)
Inverse of Lexer::lex_char: renders str as the body of a Mim string literal.
Definition
lexer.cpp:239
mim::ast::Lexer::Lexer
Lexer(Driver &driver, const fe::Src &src, std::ostream *md=nullptr)
Creates a lexer to read *.mim files (see Lexical Structure).
Definition
lexer.h:19
mim::ast::Lexer::Lexer
Lexer(Driver &driver, std::string_view buf, std::ostream *md=nullptr)
As above, but the Locations of the Toks produced have no fe::Src to resolve against.
Definition
lexer.h:22
mim::ast::Tok
Definition
tok.h:234
mim::ast::Tok::Tag
Tag
Definition
tok.h:238
driver.h
mim::ast
Definition
ast.h:16
mim::plug::math::round::c
@ c
Definition
autogen.h:297
mim::f64
double f64
Definition
types.h:35
tok.h
include
mim
ast
lexer.h
Generated by
1.18.0