nixd
Toggle main menu visibility
Loading...
Searching...
No Matches
libnixf
src
Parse
ParseSimple.cpp
Go to the documentation of this file.
1
#include "
Parser.h
"
2
3
#include "
nixf/Basic/Diagnostic.h
"
4
#include "
nixf/Basic/Nodes/Simple.h
"
5
6
#include <charconv>
7
8
using namespace
nixf
;
9
using namespace
nixf::detail
;
10
11
namespace
{
12
13
/// \brief Whether the node could be produced by non-term \p expr_simple
14
bool
mayProducedBySimple(
Node::NodeKind
NK
) {
15
switch
(
NK
) {
16
case
Node::NK_ExprVar:
17
case
Node::NK_ExprInt:
18
case
Node::NK_ExprFloat:
19
case
Node::NK_ExprSPath:
20
case
Node::NK_ExprString:
21
case
Node::NK_ExprPath:
22
case
Node::NK_ExprParen:
23
case
Node::NK_ExprAttrs:
24
case
Node::NK_ExprList:
25
return
true
;
26
default
:
27
break
;
28
}
29
return
false
;
30
}
31
32
bool
mayProducedBySimple(
const
Expr
*E) {
33
if
(!E)
34
return
false
;
35
return
mayProducedBySimple(E->
kind
());
36
}
37
38
}
// namespace
39
40
std::shared_ptr<ExprParen>
Parser::parseExprParen
() {
41
Token
L = peek();
42
auto
LParen = std::make_shared<Misc>(L.
range
());
43
assert(L.
kind
() == tok_l_paren);
44
consume();
// (
45
auto
Sync = withSync(tok_r_paren);
46
assert(LastToken &&
"LastToken should be set after consume()"
);
47
auto
Expr
=
parseExpr
();
48
if
(!
Expr
)
49
diagNullExpr
(Diags, LastToken->rCur(),
"parenthesized"
);
50
if
(ExpectResult ER = expect(tok_r_paren); ER.ok()) {
51
consume();
// )
52
auto
RParen = std::make_shared<Misc>(ER.tok().range());
53
if
(mayProducedBySimple(
Expr
.get())) {
54
Diagnostic
&D =
55
Diags.emplace_back(Diagnostic::DK_RedundantParen, LParen->range());
56
D.
tag
(
DiagnosticTag::Faded
);
57
Fix
&F = D.
fix
(
"remove ( and )"
);
58
F.
edit
(
TextEdit::mkRemoval
(LParen->range()));
59
F.
edit
(
TextEdit::mkRemoval
(RParen->range()));
60
}
61
return
std::make_shared<ExprParen>(
62
LexerCursorRange
{L.
lCur
(), ER.tok().rCur()}, std::move(
Expr
),
63
std::move(LParen), std::move(RParen));
64
}
else
{
// NOLINT(readability-else-after-return)
65
ER.diag().note(Note::NK_ToMachThis, L.
range
())
66
<< std::string(tok::spelling(tok_l_paren));
67
if
(mayProducedBySimple(
Expr
.get())) {
68
Diagnostic
&D =
69
Diags.emplace_back(Diagnostic::DK_RedundantParen, LParen->range());
70
D.
tag
(
DiagnosticTag::Faded
);
71
Fix
&F = D.
fix
(
"remove ("
);
72
F.
edit
(
TextEdit::mkRemoval
(LParen->range()));
73
}
74
return
std::make_shared<ExprParen>(
75
LexerCursorRange
{L.
lCur
(), LastToken->rCur()}, std::move(
Expr
),
76
std::move(LParen),
77
/*RParen=*/
nullptr
);
78
}
79
}
80
81
std::shared_ptr<ExprList>
Parser::parseExprList
() {
82
Token
Tok = peek();
83
if
(Tok.
kind
() != tok_l_bracket)
84
return
nullptr
;
85
consume();
// [
86
auto
Sync = withSync(tok_r_bracket);
87
assert(LastToken &&
"LastToken should be set after consume()"
);
88
LexerCursor
Begin = Tok.
lCur
();
89
std::vector<std::shared_ptr<Expr>> Exprs;
90
while
(
true
) {
91
if
(
Token
Tok = peek(); Tok.
kind
() == tok_r_bracket)
92
break
;
93
std::shared_ptr<Expr>
Expr
=
parseExprSelect
();
94
if
(!
Expr
)
95
break
;
96
Exprs.emplace_back(std::move(
Expr
));
97
}
98
if
(ExpectResult ER = expect(tok_r_bracket); ER.ok())
99
consume();
100
else
101
ER.diag().note(Note::NK_ToMachThis, Tok.
range
())
102
<< std::string(tok::spelling(tok_l_bracket));
103
return
std::make_shared<ExprList>(
LexerCursorRange
{Begin, LastToken->rCur()},
104
std::move(Exprs));
105
}
106
107
std::shared_ptr<Expr>
Parser::parseExprSimple
() {
108
Token
Tok = peek();
109
switch
(Tok.
kind
()) {
110
case
tok_uri: {
111
// URI is desugared into string
112
consume();
113
auto
Literal = std::string(Tok.
view
());
114
// Create the string used for this URI
115
auto
Parts = std::make_shared<InterpolatedParts>(
116
Tok.
range
(), std::vector<InterpolablePart>{
117
InterpolablePart{std::move(Literal)},
118
});
119
auto
Str = std::make_shared<ExprString>(Tok.
range
(), std::move(Parts));
120
// Report warning about URL deprecation.
121
Diagnostic
&D =
122
Diags.emplace_back(Diagnostic::DK_DeprecatedURL, Tok.
range
());
123
Fix
&F = D.
fix
(
"convert it to string"
);
124
// Insert a pair of quotes
125
F.
edit
(
TextEdit::mkInsertion
(Tok.
lCur
(),
"\""
));
126
F.
edit
(
TextEdit::mkInsertion
(Tok.
rCur
(),
"\""
));
127
return
Str;
128
}
129
case
tok_id: {
130
consume();
131
auto
ID =
132
std::make_shared<Identifier>(Tok.
range
(), std::string(Tok.
view
()));
133
return
std::make_shared<ExprVar>(Tok.
range
(), std::move(ID));
134
}
135
case
tok_int: {
136
consume();
137
NixInt
N = 0;
138
auto
[Ptr, Errc] = std::from_chars(Tok.
view
().begin(), Tok.
view
().end(), N);
139
if
(Errc != std::errc()) {
140
// Cannot decode int from tok_int.
141
assert(Errc == std::errc::result_out_of_range);
142
// emit a diagnostic saying we cannot decode integer to NixInt.
143
Diags.emplace_back(Diagnostic::DK_IntTooBig, Tok.
range
());
144
}
145
return
std::make_shared<ExprInt>(Tok.
range
(), N);
146
}
147
case
tok_float: {
148
consume();
149
// libc++ doesn't support std::from_chars for floating point numbers.
150
NixFloat
N = std::strtof(std::string(Tok.
view
()).c_str(),
nullptr
);
151
return
std::make_shared<ExprFloat>(Tok.
range
(), N);
152
}
153
case
tok_spath: {
154
consume();
155
return
std::make_shared<ExprSPath>(
156
Tok.
range
(), std::string(Tok.
view
().substr(1, Tok.
view
().size() - 2)));
157
}
158
case
tok_dquote:
// " - normal strings
159
return
parseString
(
/*IsIndented=*/
false
);
160
case
tok_quote2:
// '' - indented strings
161
return
parseString
(
/*IsIndented=*/
true
);
162
case
tok_path_fragment:
163
return
parseExprPath
();
164
case
tok_l_paren:
165
return
parseExprParen
();
166
case
tok_kw_rec:
167
case
tok_l_curly:
168
return
parseExprAttrs
();
169
case
tok_l_bracket:
170
return
parseExprList
();
171
default
:
172
return
nullptr
;
173
}
174
}
Diagnostic.h
NK
Note::NoteKind NK
Definition
Lexer.cpp:40
Simple.h
nixf::Diagnostic::fix
Fix & fix(std::string Message)
Definition
Diagnostic.h:203
nixf::Expr
Definition
Basic.h:70
nixf::Fix
Definition
Diagnostic.h:57
nixf::Fix::edit
Fix & edit(TextEdit Edit)
Definition
Diagnostic.h:65
nixf::LexerCursorRange
Definition
Range.h:105
nixf::LexerCursor
A point in the source file.
Definition
Range.h:57
nixf::Node::NodeKind
NodeKind
Definition
Basic.h:14
nixf::Node::kind
NodeKind kind() const
Definition
Basic.h:34
nixf::Parser::parseExprParen
std::shared_ptr< ExprParen > parseExprParen()
Definition
ParseSimple.cpp:40
nixf::Parser::parseExpr
std::shared_ptr< Expr > parseExpr()
Definition
ParseExpr.cpp:76
nixf::Parser::parseString
std::shared_ptr< ExprString > parseString(bool IsIndented)
Definition
ParseStrings.cpp:111
nixf::Parser::parseExprSelect
std::shared_ptr< Expr > parseExprSelect()
Definition
ParseExpr.cpp:6
nixf::Parser::parseExprPath
std::shared_ptr< Expr > parseExprPath()
Parse paths.
Definition
ParseStrings.cpp:29
nixf::Parser::parseExprSimple
std::shared_ptr< Expr > parseExprSimple()
Definition
ParseSimple.cpp:107
nixf::Parser::parseExprList
std::shared_ptr< ExprList > parseExprList()
Definition
ParseSimple.cpp:81
nixf::Parser::parseExprAttrs
std::shared_ptr< ExprAttrs > parseExprAttrs()
Definition
ParseAttrs.cpp:195
nixf::PartialDiagnostic::tag
void tag(DiagnosticTag Tag)
Definition
Diagnostic.h:96
nixf::TextEdit::mkRemoval
static TextEdit mkRemoval(LexerCursorRange RemovingRange)
Definition
Diagnostic.h:39
nixf::TextEdit::mkInsertion
static TextEdit mkInsertion(LexerCursor P, std::string NewText)
Definition
Diagnostic.h:35
nixf::Token
A token. With it's kind, and the range in source code.
Definition
Token.h:14
nixf::Token::lCur
LexerCursor lCur() const
Definition
Token.h:22
nixf::Token::kind
tok::TokenKind kind() const
Definition
Token.h:24
nixf::Token::range
LexerCursorRange range() const
Definition
Token.h:25
nixf::Token::rCur
LexerCursor rCur() const
Definition
Token.h:23
nixf::Token::view
std::string_view view() const
Definition
Token.h:26
Diagnostic
Definition
Diagnostic.cpp.py:1
nixf::detail
Definition
src/Parse/Parser.h:22
nixf::detail::diagNullExpr
Diagnostic & diagNullExpr(std::vector< Diagnostic > &Diags, LexerCursor Loc, std::string As)
Definition
ParseSupport.cpp:11
nixf
Definition
Diagnostic.h:19
nixf::DiagnosticTag::Faded
@ Faded
Definition
Diagnostic.h:75
nixf::NixInt
int64_t NixInt
Definition
Simple.h:12
nixf::NixFloat
double NixFloat
Definition
Simple.h:13
Parser.h
Parser for the Nix expression language.
Generated by
1.17.0