1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-27 21:01:16 +02:00

* Finished the ATerm-less parser.

This commit is contained in:
Eelco Dolstra 2010-04-12 23:33:23 +00:00
parent 0d272fca79
commit 10e8b1fd15
6 changed files with 68 additions and 102 deletions

View file

@ -44,99 +44,38 @@ struct ParseData
};
#if 0
static string showAttrPath(ATermList attrPath)
static string showAttrPath(const vector<string> & attrPath)
{
string s;
for (ATermIterator i(attrPath); i; ++i) {
foreach (vector<string>::const_iterator, i, attrPath) {
if (!s.empty()) s += '.';
s += aterm2String(*i);
s += *i;
}
return s;
}
struct Tree
static void addAttr(ExprAttrs * attrs, const vector<string> & attrPath, Expr * e, const Pos & pos)
{
Expr leaf; ATerm pos; bool recursive;
typedef std::map<ATerm, Tree> Children;
Children children;
Tree() { leaf = 0; recursive = true; }
};
static ATermList buildAttrs(const Tree & t, ATermList & nonrec)
{
ATermList res = ATempty;
for (Tree::Children::const_reverse_iterator i = t.children.rbegin();
i != t.children.rend(); ++i)
if (!i->second.recursive)
nonrec = ATinsert(nonrec, makeBind(i->first, i->second.leaf, i->second.pos));
else
res = ATinsert(res, i->second.leaf
? makeBind(i->first, i->second.leaf, i->second.pos)
: makeBind(i->first, makeAttrs(buildAttrs(i->second, nonrec)), makeNoPos()));
return res;
}
#endif
static void fixAttrs(ExprAttrs & attrs)
{
#if 0
Tree attrs;
/* This ATermMap is needed to ensure that the `leaf' fields in the
Tree nodes are not garbage collected. */
ATermMap gcRoots;
for (ATermIterator i(as); i; ++i) {
ATermList names, attrPath; Expr src, e; ATerm name, pos;
if (matchInherit(*i, src, names, pos)) {
bool fromScope = matchScope(src);
for (ATermIterator j(names); j; ++j) {
if (attrs.children.find(*j) != attrs.children.end())
throw ParseError(format("duplicate definition of attribute `%1%' at %2%")
% showAttrPath(ATmakeList1(*j)) % showPos(pos));
Tree & t(attrs.children[*j]);
Expr leaf = fromScope ? makeVar(*j) : makeSelect(src, *j);
gcRoots.set(leaf, leaf);
t.leaf = leaf;
t.pos = pos;
if (recursive && fromScope) t.recursive = false;
unsigned int n = 0;
foreach (vector<string>::const_iterator, i, attrPath) {
n++;
if (attrs->attrs[*i]) {
ExprAttrs * attrs2 = dynamic_cast<ExprAttrs *>(attrs->attrs[*i]);
if (!attrs2)
throw ParseError(format("attribute `%1%' at %2% already defined at <SOMEWHERE>")
% showAttrPath(attrPath) % pos);
attrs = attrs2;
} else {
if (n == attrPath.size())
attrs->attrs[*i] = e;
else {
ExprAttrs * nested = new ExprAttrs;
attrs->attrs[*i] = nested;
attrs = nested;
}
}
else if (matchBindAttrPath(*i, attrPath, e, pos)) {
Tree * t(&attrs);
for (ATermIterator j(attrPath); j; ) {
name = *j; ++j;
if (t->leaf) throw ParseError(format("attribute set containing `%1%' at %2% already defined at %3%")
% showAttrPath(attrPath) % showPos(pos) % showPos(t->pos));
t = &(t->children[name]);
}
if (t->leaf)
throw ParseError(format("duplicate definition of attribute `%1%' at %2% and %3%")
% showAttrPath(attrPath) % showPos(pos) % showPos(t->pos));
if (!t->children.empty())
throw ParseError(format("duplicate definition of attribute `%1%' at %2%")
% showAttrPath(attrPath) % showPos(pos));
t->leaf = e; t->pos = pos;
}
else abort(); /* can't happen */
}
ATermList nonrec = ATempty;
ATermList rec = buildAttrs(attrs, nonrec);
return recursive ? makeRec(rec, nonrec) : makeAttrs(rec);
#endif
}
@ -307,7 +246,7 @@ void yyerror(YYLTYPE * loc, yyscan_t scanner, ParseData * data, const char * err
char * id;
char * path;
char * uri;
std::list<std::string> * ids;
std::vector<std::string> * ids;
std::vector<nix::Expr *> * string_parts;
}
@ -360,7 +299,7 @@ expr_function
| WITH expr ';' expr_function
{ $$ = new ExprWith(CUR_POS, $2, $4); }
| LET binds IN expr_function
{ $2->attrs["<let-body>"] = $4; $2->recursive = true; fixAttrs(*$2); $$ = new ExprSelect($2, "<let-body>"); }
{ $2->attrs["<let-body>"] = $4; $2->recursive = true; $$ = new ExprSelect($2, "<let-body>"); }
| expr_if
;
@ -418,11 +357,11 @@ expr_simple
/* Let expressions `let {..., body = ...}' are just desugared
into `(rec {..., body = ...}).body'. */
| LET '{' binds '}'
{ fixAttrs(*$3); $3->recursive = true; $$ = new ExprSelect($3, "body"); }
{ $3->recursive = true; $$ = new ExprSelect($3, "body"); }
| REC '{' binds '}'
{ fixAttrs(*$3); $3->recursive = true; $$ = $3; }
{ $3->recursive = true; $$ = $3; }
| '{' binds '}'
{ fixAttrs(*$2); $$ = $2; }
{ $$ = $2; }
| '[' expr_list ']' { $$ = $2; }
;
@ -439,16 +378,16 @@ ind_string_parts
;
binds
: binds ID '=' expr ';' { $$ = $1; $$->attrs[$2] = $4; }
: binds attrpath '=' expr ';' { $$ = $1; addAttr($$, *$2, $4, CUR_POS); }
| binds INHERIT ids ';'
{ $$ = $1;
foreach (list<string>::iterator, i, *$3)
foreach (vector<string>::iterator, i, *$3)
$$->inherited.push_back(*i);
}
| binds INHERIT '(' expr ')' ids ';'
{ $$ = $1;
/* !!! Should ensure sharing of the expression in $4. */
foreach (list<string>::iterator, i, *$6)
foreach (vector<string>::iterator, i, *$6)
$$->attrs[*i] = new ExprSelect($4, *i);
}
| { $$ = new ExprAttrs; }
@ -456,12 +395,12 @@ binds
ids
: ids ID { $$ = $1; $1->push_back($2); /* !!! dangerous */ }
| { $$ = new list<string>; }
| { $$ = new vector<string>; }
;
attrpath
: attrpath '.' ID { $$ = ATinsert($1, $3); }
| ID { $$ = ATmakeList1($1); }
: attrpath '.' ID { $$ = $1; $1->push_back($3); }
| ID { $$ = new vector<string>; $$->push_back($1); }
;
expr_list