forked from lix-project/lix
decouple parser and EvalState
there's no reason the parser itself should be doing semantic analysis
like bindVars. split this bit apart (retaining the previous name in
EvalState) and have the parser really do *only* parsing, decoupled from
EvalState.
(cherry picked from commit b596cc9e7960b9256bcd557334d81e9d555be5a2)
Change-Id: I481a7623afc783e9d28a6eb4627552cf8a780986
This commit is contained in:
parent
faaae9d045
commit
92693973b6
|
@ -17,6 +17,7 @@
|
|||
#include "gc-small-vector.hh"
|
||||
#include "fetch-to-store.hh"
|
||||
#include "flake/flakeref.hh"
|
||||
#include "parser-tab.hh"
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
|
@ -2806,6 +2807,22 @@ std::optional<std::string> EvalState::resolveSearchPathPath(const SearchPath::Pa
|
|||
return res;
|
||||
}
|
||||
|
||||
|
||||
Expr * EvalState::parse(
|
||||
char * text,
|
||||
size_t length,
|
||||
Pos::Origin origin,
|
||||
const SourcePath & basePath,
|
||||
std::shared_ptr<StaticEnv> & staticEnv)
|
||||
{
|
||||
auto result = parseExprFromBuf(text, length, origin, basePath, symbols, positions);
|
||||
|
||||
result->bindVars(*this, staticEnv);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
std::string ExternalValueBase::coerceToString(const Pos & pos, NixStringContext & context, bool copyMore, bool copyToStore) const
|
||||
{
|
||||
throw TypeError({
|
||||
|
|
|
@ -154,7 +154,7 @@ or { return OR_KW; }
|
|||
} catch (const boost::bad_lexical_cast &) {
|
||||
throw ParseError({
|
||||
.msg = hintfmt("invalid integer '%1%'", yytext),
|
||||
.errPos = state->state.positions[CUR_POS],
|
||||
.errPos = state->positions[CUR_POS],
|
||||
});
|
||||
}
|
||||
return INT;
|
||||
|
@ -164,7 +164,7 @@ or { return OR_KW; }
|
|||
if (errno != 0)
|
||||
throw ParseError({
|
||||
.msg = hintfmt("invalid float '%1%'", yytext),
|
||||
.errPos = state->state.positions[CUR_POS],
|
||||
.errPos = state->positions[CUR_POS],
|
||||
});
|
||||
return FLOAT;
|
||||
}
|
||||
|
@ -293,7 +293,7 @@ or { return OR_KW; }
|
|||
<INPATH_SLASH><<EOF>> {
|
||||
throw ParseError({
|
||||
.msg = hintfmt("path has a trailing slash"),
|
||||
.errPos = state->state.positions[CUR_POS],
|
||||
.errPos = state->positions[CUR_POS],
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -37,8 +37,8 @@ struct ParserLocation {
|
|||
};
|
||||
|
||||
struct ParserState {
|
||||
EvalState & state;
|
||||
SymbolTable & symbols;
|
||||
PosTable & positions;
|
||||
Expr * result;
|
||||
SourcePath basePath;
|
||||
PosTable::Origin origin;
|
||||
|
@ -56,16 +56,16 @@ inline void ParserState::dupAttr(const AttrPath & attrPath, const PosIdx pos, co
|
|||
{
|
||||
throw ParseError({
|
||||
.msg = hintfmt("attribute '%1%' already defined at %2%",
|
||||
showAttrPath(state.symbols, attrPath), state.positions[prevPos]),
|
||||
.errPos = state.positions[pos]
|
||||
showAttrPath(symbols, attrPath), positions[prevPos]),
|
||||
.errPos = positions[pos]
|
||||
});
|
||||
}
|
||||
|
||||
inline void ParserState::dupAttr(Symbol attr, const PosIdx pos, const PosIdx prevPos)
|
||||
{
|
||||
throw ParseError({
|
||||
.msg = hintfmt("attribute '%1%' already defined at %2%", state.symbols[attr], state.positions[prevPos]),
|
||||
.errPos = state.positions[pos]
|
||||
.msg = hintfmt("attribute '%1%' already defined at %2%", symbols[attr], positions[prevPos]),
|
||||
.errPos = positions[pos]
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -146,13 +146,13 @@ inline Formals * ParserState::validateFormals(Formals * formals, PosIdx pos, Sym
|
|||
if (duplicate)
|
||||
throw ParseError({
|
||||
.msg = hintfmt("duplicate formal function argument '%1%'", symbols[duplicate->first]),
|
||||
.errPos = state.positions[duplicate->second]
|
||||
.errPos = positions[duplicate->second]
|
||||
});
|
||||
|
||||
if (arg && formals->has(arg))
|
||||
throw ParseError({
|
||||
.msg = hintfmt("duplicate formal function argument '%1%'", symbols[arg]),
|
||||
.errPos = state.positions[pos]
|
||||
.errPos = positions[pos]
|
||||
});
|
||||
|
||||
return formals;
|
||||
|
@ -256,7 +256,7 @@ inline Expr * ParserState::stripIndentation(const PosIdx pos,
|
|||
|
||||
inline PosIdx ParserState::at(const ParserLocation & loc)
|
||||
{
|
||||
return state.positions.add(origin, loc.first_line, loc.first_column);
|
||||
return positions.add(origin, loc.first_line, loc.first_column);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,6 +31,18 @@
|
|||
#define YY_DECL int yylex \
|
||||
(YYSTYPE * yylval_param, YYLTYPE * yylloc_param, yyscan_t yyscanner, nix::ParserState * state)
|
||||
|
||||
namespace nix {
|
||||
|
||||
Expr * parseExprFromBuf(
|
||||
char * text,
|
||||
size_t length,
|
||||
Pos::Origin origin,
|
||||
const SourcePath & basePath,
|
||||
SymbolTable & symbols,
|
||||
PosTable & positions);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@ -51,7 +63,7 @@ void yyerror(YYLTYPE * loc, yyscan_t scanner, ParserState * state, const char *
|
|||
{
|
||||
throw ParseError({
|
||||
.msg = hintfmt(error),
|
||||
.errPos = state->state.positions[state->at(*loc)]
|
||||
.errPos = state->positions[state->at(*loc)]
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -140,7 +152,7 @@ expr_function
|
|||
{ if (!$2->dynamicAttrs.empty())
|
||||
throw ParseError({
|
||||
.msg = hintfmt("dynamic attributes not allowed in let"),
|
||||
.errPos = state->state.positions[CUR_POS]
|
||||
.errPos = state->positions[CUR_POS]
|
||||
});
|
||||
$$ = new ExprLet($2, $4);
|
||||
}
|
||||
|
@ -230,7 +242,7 @@ expr_simple
|
|||
if (noURLLiterals)
|
||||
throw ParseError({
|
||||
.msg = hintfmt("URL literals are disabled"),
|
||||
.errPos = state->state.positions[CUR_POS]
|
||||
.errPos = state->positions[CUR_POS]
|
||||
});
|
||||
$$ = new ExprString(std::string($1));
|
||||
}
|
||||
|
@ -326,7 +338,7 @@ attrs
|
|||
} else
|
||||
throw ParseError({
|
||||
.msg = hintfmt("dynamic attributes not allowed in inherit"),
|
||||
.errPos = state->state.positions[state->at(@2)]
|
||||
.errPos = state->positions[state->at(@2)]
|
||||
});
|
||||
}
|
||||
| { $$ = new AttrPath; }
|
||||
|
@ -393,17 +405,18 @@ formal
|
|||
|
||||
namespace nix {
|
||||
|
||||
Expr * EvalState::parse(
|
||||
Expr * parseExprFromBuf(
|
||||
char * text,
|
||||
size_t length,
|
||||
Pos::Origin origin,
|
||||
const SourcePath & basePath,
|
||||
std::shared_ptr<StaticEnv> & staticEnv)
|
||||
SymbolTable & symbols,
|
||||
PosTable & positions)
|
||||
{
|
||||
yyscan_t scanner;
|
||||
ParserState state {
|
||||
.state = *this,
|
||||
.symbols = symbols,
|
||||
.positions = positions,
|
||||
.basePath = basePath,
|
||||
.origin = {origin},
|
||||
};
|
||||
|
@ -414,8 +427,6 @@ Expr * EvalState::parse(
|
|||
yy_scan_buffer(text, length, scanner);
|
||||
yyparse(scanner, &state);
|
||||
|
||||
state.result->bindVars(*this, staticEnv);
|
||||
|
||||
return state.result;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue