summaryrefslogtreecommitdiffabout
path: root/src/bind-gram.y
authorSergey Poznyakoff <gray@gnu.org.ua>2011-05-20 06:17:20 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2011-05-20 06:17:20 (GMT)
commitd253fa956809a1497583212109d33fd4f1a05b31 (patch) (side-by-side diff)
treebf48aced94192d54b49ac09755ed2e6d88514d70 /src/bind-gram.y
parentbcab0df28d7e87f99da29a32327787c25261273e (diff)
downloadgrecs-d253fa956809a1497583212109d33fd4f1a05b31.tar.gz
grecs-d253fa956809a1497583212109d33fd4f1a05b31.tar.bz2
Fix bind parser.
* src/bind-gram.y: Special handling for the controls block. * src/bind-lex.l: Handle "controls" separately. * src/lookup.c (grecs_find_node): Handle single dot path (root node). (grecs_match_first): Likewise. (grecs_match_next): Return NULL if buf is NULL. * tests/parser-bind.at: Update.
Diffstat (limited to 'src/bind-gram.y') (more/less context) (ignore whitespace changes)
-rw-r--r--src/bind-gram.y86
1 files changed, 44 insertions, 42 deletions
diff --git a/src/bind-gram.y b/src/bind-gram.y
index 621070e..fadd3f5 100644
--- a/src/bind-gram.y
+++ b/src/bind-gram.y
@@ -49,12 +49,12 @@ static struct grecs_value *stmtlist_to_value(struct grecs_node *node);
struct { struct grecs_node *head, *tail; } node_list;
}
-%token <ident> BIND_IDENT
+%token <ident> BIND_IDENT BIND_CONTROLS
%token <string> BIND_STRING
%type <string> string
-%type <svalue> value
+%type <svalue> value ctlsub
%type <pvalue> vallist tag
-%type <list> vlist
+%type <list> vlist ctllist
%type <node> stmt simple block
%type <node_list> stmtlist
@@ -110,31 +110,38 @@ simple : BIND_IDENT vallist ';'
}
;
-block : BIND_IDENT tag '{' stmtlist '}' opt_sc
+block : BIND_IDENT tag '{' stmtlist '}' ';'
{
$$ = grecs_node_create(grecs_node_block, &$1.locus);
$$->ident = $1.string;
$$->v.value = $2;
grecs_node_bind($$, $4.head, 1);
}
+ | BIND_CONTROLS '{' ctlsub '}' ';'
+ /* Special case:
+
+ controls {
+ inet 127.0.0.1 port 953
+ allow { 127.0.0.1; 127.0.0.2; } keys { "rndc-key"; };
+ };
+
+ This produces:
+
+ .controls: (inet, 127.0.0.1, port, 953, allow, \
+ (127.0.0.1, 127.0.0.2), keys, (rndc-key))
+ */
+ {
+ $$ = grecs_node_create(grecs_node_stmt, &$1.locus);
+ $$->ident = $1.string;
+ $$->v.value = grecs_value_ptr_from_static(&$3);
+ }
;
tag : /* empty */
{
$$ = NULL;
}
- | BIND_IDENT
- {
- $$ = grecs_malloc(sizeof($$[0]));
- $$->type = GRECS_TYPE_STRING;
- $$->v.string = $1.string;
- }
- | BIND_STRING
- {
- $$ = grecs_malloc(sizeof($$[0]));
- $$->type = GRECS_TYPE_STRING;
- $$->v.string = $1;
- }
+ | vallist
;
vallist : vlist
@@ -169,30 +176,6 @@ vlist : value
{
grecs_list_append($1, grecs_value_ptr_from_static(&$2));
}
- | vlist BIND_IDENT '{' stmtlist '}'
- /* This production handles constructs that don't fit well into
- hierarchical structure, namely, the "controls" statement, e.g.:
-
- controls {
- inet 127.0.0.1 port 953
- allow { 127.0.0.1; 127.0.0.2; } keys { "rndc-key"; };
- };
-
- This statement produces:
-
- .controls.inet: 127.0.0.1 port 953 allow (127.0.0.1) keys
- (rndc-key)
- */
- {
- struct grecs_value *val = grecs_malloc(sizeof(*val));
- val->type = GRECS_TYPE_STRING;
- val->v.string = $2.string;
- grecs_list_append($1, val);
-
- val = stmtlist_to_value($4.head);
- /* FIXME: Free $4 */
- grecs_list_append($1, val);
- }
;
value : string
@@ -209,8 +192,27 @@ string : BIND_STRING
}
;
-opt_sc : /* empty */
- | ';'
+ctlsub : ctllist ';'
+ {
+ $$.type = GRECS_TYPE_LIST;
+ $$.v.list = $1;
+ }
+ ;
+
+ctllist : value
+ {
+ $$ = grecs_value_list_create();
+ grecs_list_append($$, grecs_value_ptr_from_static(&$1));
+ }
+ | ctllist value
+ {
+ grecs_list_append($1, grecs_value_ptr_from_static(&$2));
+ }
+ | ctllist '{' stmtlist '}'
+ {
+ grecs_list_append($1, stmtlist_to_value($3.head));
+ /* FIXME: Free $3 */
+ }
;
%%

Return to:

Send suggestions and report system problems to the System administrator.