From 0a623a10c7e89a80b6dc74445a0ae6240f65723e Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 13 Jul 2011 12:19:57 +0000 Subject: * Allow a default value in attribute selection by writing x.y.z or default (as originally proposed in https://mail.cs.uu.nl/pipermail/nix-dev/2009-September/002989.html). For instance, an expression like stdenv.lib.attrByPath ["features" "ckSched"] false args can now be written as args.features.ckSched or false --- src/libexpr/parser.y | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) (limited to 'src/libexpr/parser.y') diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index 49bd7bfa5f..ec194a516a 100644 --- a/src/libexpr/parser.y +++ b/src/libexpr/parser.y @@ -237,7 +237,7 @@ void yyerror(YYLTYPE * loc, yyscan_t scanner, ParseData * data, const char * err char * id; // !!! -> Symbol char * path; char * uri; - std::vector * ids; + std::vector * attrNames; std::vector * string_parts; } @@ -247,14 +247,15 @@ void yyerror(YYLTYPE * loc, yyscan_t scanner, ParseData * data, const char * err %type binds %type formals %type formal -%type ids attrpath +%type attrs attrpath %type string_parts ind_string_parts +%type attr %token ID ATTRPATH %token STR IND_STR %token INT %token PATH %token URI -%token IF THEN ELSE ASSERT WITH LET IN REC INHERIT EQ NEQ AND OR IMPL +%token IF THEN ELSE ASSERT WITH LET IN REC INHERIT EQ NEQ AND OR IMPL OR_KW %token DOLLAR_CURLY /* == ${ */ %token IND_STRING_OPEN IND_STRING_CLOSE %token ELLIPSIS @@ -326,7 +327,13 @@ expr_app expr_select : expr_simple '.' attrpath - { $$ = new ExprSelect($1, *$3); } + { $$ = new ExprSelect($1, *$3, 0); } + | expr_simple '.' attrpath OR_KW expr_select + { $$ = new ExprSelect($1, *$3, $5); } + | /* Backwards compatibility: because Nixpkgs has a rarely used + function named ‘or’, allow stuff like ‘map or [...]’. */ + expr_simple OR_KW + { $$ = new ExprApp($1, new ExprVar(data->symbols.create("or"))); } | expr_simple { $$ = $1; } ; @@ -370,7 +377,7 @@ ind_string_parts binds : binds attrpath '=' expr ';' { $$ = $1; addAttr($$, *$2, $4, makeCurPos(@2, data)); } - | binds INHERIT ids ';' + | binds INHERIT attrs ';' { $$ = $1; foreach (AttrPath::iterator, i, *$3) { if ($$->attrs.find(*i) != $$->attrs.end()) @@ -379,26 +386,31 @@ binds $$->attrs[*i] = ExprAttrs::AttrDef(*i, pos); } } - | binds INHERIT '(' expr ')' ids ';' + | binds INHERIT '(' expr ')' attrs ';' { $$ = $1; /* !!! Should ensure sharing of the expression in $4. */ foreach (vector::iterator, i, *$6) { if ($$->attrs.find(*i) != $$->attrs.end()) dupAttr(*i, makeCurPos(@6, data), $$->attrs[*i].pos); $$->attrs[*i] = ExprAttrs::AttrDef(new ExprSelect($4, *i), makeCurPos(@6, data)); - }} - + } + } | { $$ = new ExprAttrs; } ; -ids - : ids ID { $$ = $1; $1->push_back(data->symbols.create($2)); /* !!! dangerous */ } +attrs + : attrs attr { $$ = $1; $1->push_back(data->symbols.create($2)); /* !!! dangerous */ } | { $$ = new vector; } ; attrpath - : attrpath '.' ID { $$ = $1; $1->push_back(data->symbols.create($3)); } - | ID { $$ = new vector; $$->push_back(data->symbols.create($1)); } + : attrpath '.' attr { $$ = $1; $1->push_back(data->symbols.create($3)); } + | attr { $$ = new vector; $$->push_back(data->symbols.create($1)); } + ; + +attr + : ID { $$ = $1; } + | OR_KW { $$ = "or"; } ; expr_list -- cgit 1.4.1