root/lm-sensors/trunk/lib/conf-parse.y @ 91

Revision 91, 8.0 KB (checked in by frodo, 14 years ago)

The first bunch of library files

These are the relatively well-tested files. They allow you to parse a
configuration file, and to build an internal abstract syntax tree.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1%{
2/*
3    conf-parse.y - Part of libsensors, a Linux library for reading sensor data.
4    Copyright (c) 1998  Frodo Looijaard <frodol@dds.nl>
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#define YYERROR_VERBOSE
22
23#include <stdio.h>
24#include <string.h>
25#include <stdlib.h>
26
27#include "data.h"
28#include "general.h"
29#include "error.h"
30
31/* These two functions are defined in conf-lex.l */
32extern int sensors_yylex(void);
33extern char sensors_lex_error[];
34extern int sensors_yylineno;
35
36static void sensors_yyerror(const char *err);
37static sensors_expr *malloc_expr(void);
38
39static sensors_chip *current_chip = NULL;
40
41#define bus_add_el(el) sensors_add_array_el(el,\
42                                      (void **) &sensors_config_busses,\
43                                      &sensors_config_busses_count,\
44                                      &sensors_config_busses_max,\
45                                      sizeof(sensors_bus))
46#define label_add_el(el) sensors_add_array_el(el,\
47                                        (void **) &current_chip->labels,\
48                                        &current_chip->labels_count,\
49                                        &current_chip->labels_max,\
50                                        sizeof(sensors_label));
51#define set_add_el(el) sensors_add_array_el(el,\
52                                      (void **) &current_chip->sets,\
53                                      &current_chip->sets_count,\
54                                      &current_chip->sets_max,\
55                                      sizeof(sensors_set));
56#define compute_add_el(el) sensors_add_array_el(el,\
57                                          (void **) &current_chip->computes,\
58                                          &current_chip->computes_count,\
59                                          &current_chip->computes_max,\
60                                          sizeof(sensors_compute));
61#define chip_add_el(el) sensors_add_array_el(el,\
62                                       (void **) &sensors_config_chips,\
63                                       &sensors_config_chips_count,\
64                                       &sensors_config_chips_max,\
65                                       sizeof(sensors_chip));
66
67#define fits_add_el(el,list) sensors_add_array_el(el,\
68                                                  (void **) &(list).fits,\
69                                                  &(list).fits_count,\
70                                                  &(list).fits_max, \
71                                                  sizeof(sensors_chip_name));
72
73/* YYERROR can only be called in rules, not in other functions, so this must
74   be a macro */
75#define check_current_chip()\
76  do { if (! current_chip) {\
77      sensors_yyerror("Label, Set or Compute statement before first chip statement");\
78      YYERROR;\
79    }\
80  } while (0)
81
82%}
83
84%union {
85  double value;
86  char *name;
87  void *nothing;
88  sensors_chip_name_list chips;
89  sensors_expr *expr;
90  int bus;
91  sensors_chip_name chip;
92
93
94%left <nothing> '-' '+'
95%left <nothing> '*' '/'
96%left <nothing> NEG
97
98%token <nothing> ','
99%token <nothing> EOL
100%token <nothing> BUS
101%token <nothing> LABEL
102%token <nothing> SET
103%token <nothing> CHIP
104%token <nothing> COMPUTE
105%token <value> FLOAT
106%token <name> NAME
107%token <nothing> ERROR
108
109%type <chips> chip_name_list
110%type <expr> expression
111%type <bus> i2cbus_name
112%type <name> adapter_name
113%type <name> algorithm_name
114%type <name> function_name
115%type <name> string
116%type <chip> chip_name
117
118%start input
119
120%%
121
122input:    /* empty */
123        | input line
124;
125
126line:     bus_statement EOL
127        | label_statement EOL
128        | set_statement EOL
129        | chip_statement EOL
130        | compute_statement EOL
131        | error EOL
132;
133
134bus_statement:    BUS i2cbus_name adapter_name algorithm_name
135                  { sensors_bus new_el;
136                    new_el.number = $2;
137                    new_el.adapter = $3;
138                    new_el.algorithm = $4;
139                    bus_add_el(&new_el);
140                  }
141;
142
143label_statement:          LABEL function_name string
144                          { sensors_label new_el;
145                            check_current_chip();
146                            new_el.name = $2;
147                            new_el.value = $3;
148                            label_add_el(&new_el);
149                          }
150;
151
152set_statement:    SET function_name expression
153                  { sensors_set new_el;
154                    check_current_chip();
155                    new_el.name = $2;
156                    new_el.value = $3;
157                    set_add_el(&new_el);
158                  }
159;
160
161compute_statement:        COMPUTE function_name expression ',' expression
162                          { sensors_compute new_el;
163                            check_current_chip();
164                            new_el.name = $2;
165                            new_el.from_proc = $3;
166                            new_el.to_proc = $5;
167                            compute_add_el(&new_el);
168                          }
169;
170
171chip_statement:   CHIP chip_name_list
172                  { sensors_chip new_el;
173                    new_el.labels = NULL;
174                    new_el.sets = NULL;
175                    new_el.computes = NULL;
176                    new_el.labels_count = new_el.labels_max = 0;
177                    new_el.sets_count = new_el.sets_max = 0;
178                    new_el.computes_count = new_el.computes_max = 0;
179                    new_el.chips = $2;
180                    chip_add_el(&new_el);
181                    current_chip = sensors_config_chips +
182                                   sensors_config_chips_count - 1;
183                  }
184;
185
186chip_name_list:   chip_name
187                  {
188                    $$.fits = NULL;
189                    $$.fits_count = $$.fits_max = 0;
190                    fits_add_el(&$1,$$);
191                  }
192                | chip_name_list chip_name
193                  { $$ = $1;
194                    fits_add_el(&$2,$$);
195                  }
196;
197       
198expression:       FLOAT
199                  { $$ = malloc_expr();
200                    $$->data.val = $1;
201                    $$->kind = sensors_kind_val;
202                  }
203                | NAME
204                  { $$ = malloc_expr();
205                    $$->data.var = $1;
206                    $$->kind = sensors_kind_var;
207                  }
208                | expression '+' expression
209                  { $$ = malloc_expr();
210                    $$->kind = sensors_kind_sub;
211                    $$->data.subexpr.op = sensors_add;
212                    $$->data.subexpr.sub1 = $1;
213                    $$->data.subexpr.sub2 = $3;
214                  }
215                | expression '-' expression
216                  { $$ = malloc_expr();
217                    $$->kind = sensors_kind_sub;
218                    $$->data.subexpr.op = sensors_sub;
219                    $$->data.subexpr.sub1 = $1;
220                    $$->data.subexpr.sub2 = $3;
221                  }
222                | expression '*' expression
223                  { $$ = malloc_expr();
224                    $$->kind = sensors_kind_sub;
225                    $$->data.subexpr.op = sensors_multiply;
226                    $$->data.subexpr.sub1 = $1;
227                    $$->data.subexpr.sub2 = $3;
228                  }
229                | expression '/' expression
230                  { $$ = malloc_expr();
231                    $$->kind = sensors_kind_sub;
232                    $$->data.subexpr.op = sensors_divide;
233                    $$->data.subexpr.sub1 = $1;
234                    $$->data.subexpr.sub2 = $3;
235                  }
236                | '-' expression  %prec NEG
237                  { $$ = malloc_expr();
238                    $$->kind = sensors_kind_sub;
239                    $$->data.subexpr.op = sensors_negate;
240                    $$->data.subexpr.sub1 = $2;
241                    $$->data.subexpr.sub2 = NULL;
242                  }
243                | '(' expression ')'
244                  { $$ = $2; }
245;
246
247i2cbus_name:      NAME
248                  { int res = sensors_parse_i2cbus_name($1,&$$);
249                    free($1);
250                    if (res) {
251                      sensors_yyerror("Parse error in i2c bus name");
252                      YYERROR;
253                    }
254                  }
255;
256
257adapter_name:     NAME
258                  { $$ = $1; }
259;
260
261algorithm_name:   NAME
262                  { $$ = $1; }
263;
264
265function_name:    NAME
266                  { $$ = $1; }
267;
268
269string:   NAME
270          { $$ = $1; }
271;
272
273chip_name:        NAME
274                  { int res = sensors_parse_chip_name($1,&$$);
275                    free($1);
276                    if (res) {
277                      sensors_yyerror("Parse error in chip name");
278                      YYERROR;
279                    }
280                  }
281;
282
283%%
284
285void sensors_yyerror(const char *err)
286{
287  if (sensors_lex_error[0]) {
288    sensors_parse_error(sensors_lex_error,sensors_yylineno);
289    sensors_lex_error[0] = '\0';
290  } else
291    sensors_parse_error(err,sensors_yylineno);
292}
293
294sensors_expr *malloc_expr(void)
295{
296  sensors_expr *res = malloc(sizeof(sensors_expr));
297  if (! res)
298    sensors_fatal_error("malloc_expr","Allocating a new expression");
299  return res;
300}
301 
Note: See TracBrowser for help on using the browser.