parser code cleanup; and regenerated with bison 3.0.2
[platform/upstream/libconfig.git] / lib / scanner.l
1 /* -*- mode: C -*- */
2 /* --------------------------------------------------------------------------
3    libconfig - A library for processing structured configuration files
4    Copyright (C) 2005-2010  Mark A Lindner
5
6    This file is part of libconfig.
7
8    This library is free software; you can redistribute it and/or
9    modify it under the terms of the GNU Lesser General Public License
10    as published by the Free Software Foundation; either version 2.1 of
11    the License, or (at your option) any later version.
12
13    This library is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    Lesser General Public License for more details.
17
18    You should have received a copy of the GNU Library General Public
19    License along with this library; if not, see
20    <http://www.gnu.org/licenses/>.
21    ----------------------------------------------------------------------------
22 */
23
24 %option nounistd
25 %option never-interactive
26 %option reentrant
27 %option noyywrap
28 %option yylineno
29 %option nounput
30 %option bison-bridge
31 %option header-file="scanner.h"
32 %option outfile="lex.yy.c"
33 %option extra-type="struct scan_context *"
34
35 %{
36
37 #ifdef _MSC_VER
38 #pragma warning (disable: 4996)
39 #endif
40
41 #include <stdlib.h>
42 #include <ctype.h>
43 #include <string.h>
44 #include "parsectx.h"
45 #include "scanctx.h"
46 #include "grammar.h"
47 #include "wincompat.h"
48
49 #define YY_NO_INPUT // Suppress generation of useless input() function
50
51 static unsigned long long fromhex(const char *s)
52 {
53 #ifdef __MINGW32__
54
55   /* MinGW's strtoull() seems to be broken; it only returns the lower
56    * 32 bits...
57    */
58
59   const char *p = s;
60   unsigned long long val = 0;
61
62   if(*p != '0')
63     return(0);
64
65   ++p;
66
67   if(*p != 'x' && *p != 'X')
68     return(0);
69
70   for(++p; isxdigit(*p); ++p)
71   {
72     val <<= 4;
73     val |= ((*p < 'A') ? (*p & 0xF) : (9 + (*p & 0x7)));
74   }
75
76   return(val);
77
78 #else /* ! __MINGW32__ */
79
80   return(strtoull(s, NULL, 16));
81
82 #endif /* __MINGW32__ */
83 }
84
85 %}
86
87 true              [Tt][Rr][Uu][Ee]
88 false             [Ff][Aa][Ll][Ss][Ee]
89 name              [A-Za-z\*][-A-Za-z0-9_\*]*
90 integer           [-+]?[0-9]+
91 integer64         [-+]?[0-9]+L(L)?
92 hex               0[Xx][0-9A-Fa-f]+
93 hex64             0[Xx][0-9A-Fa-f]+L(L)?
94 hexchar           \\[Xx][0-9A-Fa-f]{2}
95 float             ([-+]?([0-9]*)?\.[0-9]*([eE][-+]?[0-9]+)?)|([-+]?([0-9]+)(\.[0-9]*)?[eE][-+]?[0-9]+)
96 comment           (#|\/\/).*$
97 include_open      ^[ \t]*@include[ \t]+\"
98
99 %x COMMENT STRING INCLUDE
100
101 %%
102
103 \/\*              { BEGIN COMMENT; }
104 <COMMENT>\*\/     { BEGIN INITIAL; }
105 <COMMENT>.        { /* ignore */ }
106 <COMMENT>\n       { /* ignore */ }
107
108 \"                { BEGIN STRING; }
109 <STRING>[^\"\\]+  { scanctx_append_string(yyextra, yytext); }
110 <STRING>\\n       { scanctx_append_string(yyextra, "\n"); }
111 <STRING>\\r       { scanctx_append_string(yyextra, "\r"); }
112 <STRING>\\t       { scanctx_append_string(yyextra, "\t"); }
113 <STRING>\\f       { scanctx_append_string(yyextra, "\f"); }
114 <STRING>\\\\      { scanctx_append_string(yyextra, "\\"); }
115 <STRING>\\\"      { scanctx_append_string(yyextra, "\""); }
116 <STRING>{hexchar} {
117                     char c[2] = { (char)(strtol(yytext + 2, NULL, 16) & 0xFF),
118                                   0 };
119                     scanctx_append_string(yyextra, c);
120                   }
121 <STRING>\\        { scanctx_append_string(yyextra, "\\"); }
122 <STRING>\"        {
123                     yylval->sval = scanctx_take_string(yyextra);
124                     BEGIN INITIAL;
125                     return(TOK_STRING);
126                   }
127
128 {include_open}    { BEGIN INCLUDE; }
129 <INCLUDE>[^\"\\]+ { scanctx_append_string(yyextra, yytext); }
130 <INCLUDE>\\\\     { scanctx_append_string(yyextra, "\\"); }
131 <INCLUDE>\\\"     { scanctx_append_string(yyextra, "\""); }
132 <INCLUDE>\"       {
133                     const char *error;
134                     FILE *fp = scanctx_push_include(yyextra,
135                                                     (void *)YY_CURRENT_BUFFER,
136                                                     &error);
137                     if(fp)
138                     {
139                       yyin = fp;
140                       yy_switch_to_buffer(
141                         yy_create_buffer(yyin, YY_BUF_SIZE, yyscanner),
142                         yyscanner);
143                     }
144                     else
145                     {
146                       yyextra->config->error_text = error;
147                       yyextra->config->error_file = scanctx_current_filename(
148                         yyextra);
149                       yyextra->config->error_line = libconfig_yyget_lineno(
150                         yyscanner);
151                       return TOK_ERROR;
152                     }
153                     BEGIN INITIAL;
154                   }
155
156 \n|\r|\f          { /* ignore */ }
157 [ \t]+            { /* ignore */ }
158
159 \=|\:             { return(TOK_EQUALS); }
160 ,                 { return(TOK_COMMA); }
161 \{                { return(TOK_GROUP_START); }
162 \}                { return(TOK_GROUP_END); }
163 {true}            { yylval->ival = 1; return(TOK_BOOLEAN); }
164 {false}           { yylval->ival = 0; return(TOK_BOOLEAN); }
165 {name}            { yylval->sval = yytext; return(TOK_NAME); }
166 {float}           { yylval->fval = atof(yytext); return(TOK_FLOAT); }
167 {integer}         { yylval->ival = atoi(yytext); return(TOK_INTEGER); }
168 {integer64}       { yylval->llval = atoll(yytext); return(TOK_INTEGER64); }
169 {hex}             {
170                     yylval->ival = strtoul(yytext, NULL, 16);
171                     return(TOK_HEX);
172                   }
173 {hex64}           { yylval->llval = fromhex(yytext); return(TOK_HEX64); }
174 \[                { return(TOK_ARRAY_START); }
175 \]                { return(TOK_ARRAY_END); }
176 \(                { return(TOK_LIST_START); }
177 \)                { return(TOK_LIST_END); }
178 ;                 { return(TOK_SEMICOLON); }
179 {comment}         { /* ignore */ }
180 .                 { return(TOK_GARBAGE); }
181
182 <<EOF>>           {
183                     YY_BUFFER_STATE buf = (YY_BUFFER_STATE)scanctx_pop_include(
184                       yyextra);
185                     if(buf)
186                     {
187                       yy_delete_buffer(YY_CURRENT_BUFFER, yyscanner);
188                       yy_switch_to_buffer(buf, yyscanner);
189                     }
190                     else
191                       yyterminate();
192                   }