root/lm-sensors/branches/scanner-opt-branch/lib/conf-lex.l @ 4145

Revision 4145, 6.6 KB (checked in by mmh, 7 years ago)

This patch makes all start conditions exclusive. This involves copying some
shared rules from the INITIAL s.c. into the MIDDLE s.c.

The patch also reorganizes the start conditions for easier maintenance. This
involves using a feature of flex called start condition scope.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1%{
2/*
3    conf-lex.l - Part of libsensors, a Linux library for reading sensor data.
4    Copyright (c) 1998, 1999  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#include <stdlib.h>
22#include <string.h>
23
24#include "general.h"
25#include "data.h"
26#include "conf-parse.h"
27#include "error.h"
28#include "scanner.h"
29
30static int buffer_count;
31static int buffer_max;
32static char *buffer;
33
34char sensors_lex_error[100];
35
36int sensors_yylineno;
37
38#define buffer_malloc() sensors_malloc_array(&buffer,&buffer_count,\
39                                             &buffer_max,1)
40#define buffer_free() sensors_free_array(&buffer,&buffer_count,\
41                                         &buffer_max)
42#define buffer_add_char(c) sensors_add_array_el(c,&buffer,\
43                                                &buffer_count,\
44                                                &buffer_max,1)
45#define buffer_add_string(s) sensors_add_array_els(s,strlen(s),\
46                                                   &buffer, \
47                                                   &buffer_count,&buffer_max,1)
48
49%}
50
51 /* Scanner for configuration files */
52
53%option nodefault
54%option noyywrap
55%option nounput
56
57 /* All states are exclusive */
58
59%x MIDDLE
60%x STRING
61%x ERR
62
63 /* Any whitespace-like character */
64
65BLANK           [ \f\t\v]
66
67IDCHAR          [[:alnum:]_]
68
69 /* Note: `10', `10.4' and `.4' are valid, `10.' is not */
70
71FLOAT   [[:digit:]]*\.?[[:digit:]]+
72
73 /* Only positive whole numbers are recognized here */
74
75NUM     0|([1-9][[:digit:]]*)
76
77 /* Only number between 1 and 255, octally represented. */
78
79OCTESC          (1[0-7]{0,2})|([2-7][0-7]?)|(0[1-7][0-7]?)|(00[1-7])
80
81
82%%
83
84 /*
85  * STATE: INITIAL
86  */
87
88<INITIAL>{
89
90<<EOF>>         { /* EOF from this state terminates */
91                  return 0;
92                }
93
94{BLANK}+        ; /* eat as many blanks as possible at once */
95
96{BLANK}*\n      { /* eat a bare newline (possibly preceded by blanks) */
97                  sensors_yylineno++;
98                }
99
100 /* comments */
101
102#.*             ; /* eat the rest of the line after comment char */
103
104#.*\n           { /* eat the rest of the line after comment char */
105                  sensors_yylineno++;
106                }
107
108 /* Some keywords at the beginning of lines */
109
110"label"         {
111                  sensors_yylval.line = sensors_yylineno;
112                  BEGIN(MIDDLE);
113                  return LABEL;
114                }
115
116"set"           {
117                  sensors_yylval.line = sensors_yylineno;
118                  BEGIN(MIDDLE);
119                  return SET;
120                }
121
122"compute"       {
123                  sensors_yylval.line = sensors_yylineno;
124                  BEGIN(MIDDLE);
125                  return COMPUTE;
126                }
127
128"bus"           {
129                  sensors_yylval.line = sensors_yylineno;
130                  BEGIN(MIDDLE);
131                  return BUS;
132                }
133
134"chip"          {
135                  sensors_yylval.line = sensors_yylineno;
136                  BEGIN(MIDDLE);
137                  return CHIP;
138                }
139
140"ignore"        {
141                  sensors_yylval.line = sensors_yylineno;
142                  BEGIN(MIDDLE);
143                  return IGNORE;
144                }
145
146 /* Anything else at the beginning of a line is an error */
147
148.               {
149                  yymore();
150                  BEGIN(ERR);
151                }
152}
153
154 /*
155  * STATE: ERROR
156  */
157
158<ERR>{
159
160.*(\n)?         {
161                  BEGIN(INITIAL);
162                  strcpy(sensors_lex_error,"Invalid keyword");
163                  return ERROR;
164                }
165}
166
167 /*
168  * STATE: MIDDLE
169  */
170
171<MIDDLE>{
172
173{BLANK}+        ; /* eat as many blanks as possible at once */
174
175\n              { /* newline here sends EOL token to parser */
176                  BEGIN(INITIAL);
177                  sensors_yylineno++;
178                  return EOL;
179                }
180
181<<EOF>>         { /* EOF here sends EOL token to parser also */
182                  BEGIN(INITIAL);
183                  return EOL;
184                }
185
186\\{BLANK}*\n    { /* eat an escaped newline with no state change */
187                  sensors_yylineno++;
188                }
189
190#.*             ; /* eat the rest of the line after comment char */
191
192#.*\n           { /* eat the rest of the line after comment char */
193                  BEGIN(INITIAL);
194                  sensors_yylineno++;
195                  return EOL;
196                }
197
198 /* A number */
199
200{FLOAT}         {
201                  sensors_yylval.value = atof(sensors_yytext);
202                  return FLOAT;
203                }
204
205 /* Some operators */
206
207"+"             return '+';
208"-"             return '-';
209"*"             return '*';
210"/"             return '/';
211"("             return '(';
212")"             return ')';
213","             return ',';
214"@"             return '@';
215"^"             return '^';
216"`"             return '`';
217
218 /* Quoted string */
219
220\"              {
221                  buffer_malloc();
222                  BEGIN(STRING);
223                }
224
225 /* A normal, unquoted identifier */
226
227{IDCHAR}+       {
228                  sensors_yylval.name = strdup(sensors_yytext);
229                  if (! sensors_yylval.name)
230                    sensors_fatal_error("conf-lex.l",
231                                        "Allocating a new string");
232                 
233                  return NAME;
234                }
235
236 /* anything else is bogus */
237
238.               {
239                  yymore();
240                  BEGIN(ERR);
241                }
242}
243
244 /*
245  * STATE: STRING
246  */
247
248<STRING>{
249
250 /* Oops, newline while in a string is not good */
251
252\n              |
253\\\n            {
254                  buffer_add_char("\0");
255                  strcpy(sensors_lex_error,"No matching double quote");
256                  buffer_free();
257                  BEGIN(INITIAL);
258                  return ERROR;
259                }
260
261 /* At the end */
262
263\"              {
264                  buffer_add_char("\0");
265                  sensors_yylval.name = strdup(buffer);
266                  if (! sensors_yylval.name)
267                    sensors_fatal_error("conf-lex.l",
268                                        "Allocating a new string");
269                  buffer_free();
270                  BEGIN(MIDDLE);
271                  return NAME;
272                }
273
274\\a             {
275                  buffer_add_char("\a");
276                }
277
278\\b             {
279                  buffer_add_char("\b");
280                }
281
282\\f             {
283                  buffer_add_char("\f");
284                }
285
286\\n             {
287                  buffer_add_char("\n");
288                }
289
290\\r             {
291                  buffer_add_char("\r");
292                }
293
294\\t             {
295                  buffer_add_char("\t");
296                }
297
298\\v             {
299                  buffer_add_char("\v");
300                }
301
302 /* We can't support \0, this would cause havoc! */
303
304\\{OCTESC}      {
305                  int res;
306                  sscanf(sensors_yytext+1,"%o",&res);
307                  buffer_add_char(&res);
308                }
309
310 /* Other escapes: just copy the character behind the slash */
311
312\\.             {
313                  buffer_add_char(&sensors_yytext[1]);
314                }
315
316 /* Anything else */
317
318[^\\\n\"]+      {
319                  buffer_add_string(sensors_yytext);
320                }
321}
322
323%%
324
325/*
326        Do the buffer handling manually.  This allows us to scan as many
327        config files as we need to, while cleaning up properly after each
328        one.  The "BEGIN(0)" line ensures that we start in the default state,
329        even if e.g. the previous config file was syntactically broken.
330
331        Returns 0 if successful, !0 otherwise.
332*/
333
334static YY_BUFFER_STATE scan_buf = (YY_BUFFER_STATE)0;
335
336int sensors_scanner_init(FILE *input)
337{
338        BEGIN(0);
339        if (!(scan_buf = sensors_yy_create_buffer(input, YY_BUF_SIZE)))
340                return -1;
341
342        sensors_yy_switch_to_buffer(scan_buf);
343        sensors_yylineno = 1;
344        return 0;
345}
346
347void sensors_scanner_exit(void)
348{
349        sensors_yy_delete_buffer(scan_buf);
350        scan_buf = (YY_BUFFER_STATE)0;
351}
352
Note: See TracBrowser for help on using the browser.