diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-05-20 09:17:20 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-05-20 09:17:20 +0300 |
commit | d253fa956809a1497583212109d33fd4f1a05b31 (patch) | |
tree | bf48aced94192d54b49ac09755ed2e6d88514d70 /src/bind-gram.y | |
parent | bcab0df28d7e87f99da29a32327787c25261273e (diff) | |
download | grecs-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')
-rw-r--r-- | src/bind-gram.y | 86 |
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 */ + } ; %% |