Import release 0.03
[secnet] / conffile.y
1 %token TOK_STRING
2 %token TOK_NUMBER
3 %token TOK_KEY
4
5 %start input
6
7 %{
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include "secnet.h"
12 #include "conffile_internal.h"
13 #include "util.h"
14 #define YYERROR_VERBOSE
15
16 static struct p_node *node(uint32_t type, struct p_node *l, struct p_node *r);
17
18 static struct p_node *result;
19
20 static void yyerror(char *s);
21
22 %}
23
24 %%
25
26 input: assignments { result = $1; }
27 ;
28
29 assignments: assignments assignment { $$=node(T_ALIST, $2, $1); }
30 | assignment { $$=node(T_ALIST, $1, NULL); }
31 ;
32
33 searchpath: /* empty */ { $$ = NULL; }
34 | '<' list '>' { $$ = $2; }
35 ;
36
37 dict: searchpath '{' assignments '}'
38 { $$ = node(T_DICT, $3, $1); }
39 | searchpath '{' '}' { $$ = node(T_DICT, NULL, $1); }
40 ;
41
42 path: '/' pathelements { $$ = node(T_ABSPATH, NULL, $2); }
43 | pathelements { $$ = node(T_RELPATH, NULL, $1); }
44 ;
45
46 pathelements: pathelements '/' TOK_KEY { $$ = node(T_PATHELEM, $3, $1); }
47 | TOK_KEY { $$ = node(T_PATHELEM, $1, NULL); }
48 ;
49
50 exec: item '(' list ')' { $$ = node(T_EXEC, $1, $3); }
51 | item '(' ')' { $$ = node(T_EXEC, $1, NULL); }
52 | item dict
53 { $$ = node(T_EXEC, $1, node(T_LISTITEM, $2, NULL)); }
54 ;
55
56 list: list ',' item { $$ = node(T_LISTITEM, $3, $1); }
57 | item { $$ = node(T_LISTITEM, $1, NULL); }
58 ;
59
60 assignment: TOK_KEY '=' list ';' { $$ = node(T_ASSIGNMENT, $1, $3); }
61 | TOK_KEY list ';' { $$ = node(T_ASSIGNMENT, $1, $2); }
62 | error ';' { $$ = node(T_ERROR, NULL, NULL); }
63 | error '}' { $$ = node(T_ERROR, NULL, NULL); }
64 | error ')' { $$ = node(T_ERROR, NULL, NULL); }
65 ;
66
67 item: TOK_STRING
68 | TOK_NUMBER
69 | path
70 | dict
71 | exec
72 ;
73
74 %%
75
76 static void yyerror(char *s)
77 {
78 Message(M_FATAL,"config file %s line %d: %s\n",config_file,
79 config_lineno,s);
80 }
81
82 struct p_node *parse_conffile(FILE *conffile)
83 {
84 yyin=conffile;
85 if (yyparse()!=0) {
86 fatal("Configuration file parsing failed\n");
87 }
88 if (yynerrs>0) {
89 fatal("%d error%s encountered in configuration file\n",
90 yynerrs,yynerrs==1?"":"s");
91 }
92 return result;
93 }
94
95 static struct p_node *node(uint32_t type, struct p_node *l, struct p_node *r)
96 {
97 struct p_node *rv;
98
99 rv=safe_malloc(sizeof(*rv),"p_node");
100 rv->type=type;
101 rv->loc.file=config_file;
102 rv->loc.line=config_lineno;
103 rv->l=l;
104 rv->r=r;
105 return rv;
106 }