11using namespace nixf::tok;
33std::pair<unsigned, unsigned> getBP(TokenKind Kind) {
35 case tok_op_pipe_from:
37 case tok_op_pipe_into:
66 __builtin_unreachable();
70unsigned getUnaryBP(TokenKind Kind) {
77 __builtin_unreachable();
83std::shared_ptr<Expr> Parser::parseExprOpBP(
unsigned LeftRBP) {
84 std::shared_ptr<Expr> Prefix;
85 LexerCursor LCur = lCur();
86 switch (Token Tok = peek(); Tok.kind()) {
90 assert(LastToken &&
"consume() should have set LastToken");
91 auto O = std::make_shared<Op>(Tok.range(), Tok.kind());
92 auto Expr = parseExprOpBP(getUnaryBP(Tok.kind()));
95 "unary operator " + std::string(tok::spelling(Tok.kind())));
97 std::make_shared<ExprUnaryOp>(LexerCursorRange{LCur, LastToken->rCur()},
98 std::move(O), std::move(Expr));
109 switch (Token Tok = peek(); Tok.kind()) {
110#define TOK_BIN_OP(NAME) case tok_op_##NAME:
111#include "TokenKinds.inc"
120 auto [LBP, RBP] = getBP(Tok.kind());
123 if (LeftRBP == LBP) {
125 Diags.emplace_back(Diagnostic::DK_OperatorNotAssociative,
129 assert(LastToken &&
"consume() should have set LastToken");
130 auto O = std::make_shared<Op>(Tok.range(), Tok.kind());
131 auto RHS = parseExprOpBP(RBP);
133 diagNullExpr(Diags, LastToken->rCur(),
"binary op RHS");
136 LexerCursorRange Range{Prefix->lCur(), RHS->rCur()};
137 Prefix = std::make_shared<ExprBinOp>(Range, std::move(O),
138 std::move(Prefix), std::move(RHS));
144 assert(LastToken &&
"consume() should have set LastToken");
145 auto O = std::make_shared<Op>(Tok.range(), Tok.kind());
148 LexerCursorRange Range{Prefix->lCur(), LastToken->rCur()};
149 Prefix = std::make_shared<ExprOpHasAttr>(
150 Range, std::move(O), std::move(Prefix), std::move(Path));
156 auto &D = Diags.emplace_back(Diagnostic::DK_KeywordOrIsNotBinaryOp,
158 D.fix(
"replace 'or' with '||'").edit(TextEdit(Tok.range(),
"||"));
160 assert(LastToken &&
"consume() should have set LastToken");
161 auto O = std::make_shared<Op>(Tok.range(), Tok.kind());
164 auto RHS = parseExprOpBP(getBP(tok_op_or).second);
170 LexerCursorRange Range{Prefix->lCur(), RHS->rCur()};
171 Prefix = std::make_shared<ExprBinOp>(Range, std::move(O),
172 std::move(Prefix), std::move(RHS));
std::shared_ptr< Expr > parseExprApp(int Limit=INT_MAX)
std::shared_ptr< AttrPath > parseAttrPath()
Diagnostic & diagNullExpr(std::vector< Diagnostic > &Diags, LexerCursor Loc, std::string As)
Parser for the Nix expression language.