first version upgrade
[devspec.git] / devspec.en_US / project / recutils / src / rec-sex-lex.l
bloba1f859613050feac445afdba97abd93a641b5d92
1 /* -*- mode: C -*-
2  *
3  *       File:         rec-sex.l
4  *       Date:         Sat Jan  9 16:35:18 2010
5  *
6  *       GNU recutils - Selection Expressions lexer
7  *
8  */
10 /* Copyright (C) 2010-2019 Jose E. Marchesi */
12 /* This program is free software: you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation, either version 3 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24  */
26 /* Automake needs this.  */
27 %option outfile="lex.yy.c"
28 %option prefix="sex"
29 %option pointer
30 %option noyywrap
31 %option reentrant
32 %option bison-bridge
33 %option extra-type="void *"
35 %option header-file="rec-sex-lex.h"
36 %option nounput
37 %option noinput
38 %top {
39    /* This code goes at the "top" of the generated file.  */
40    #include <config.h>
44 #include <rec-utils.h>
46 #include <rec-sex-ast.h>
47 #include <rec-sex-parser.h>
48 #include <rec-sex-tab.h>
50 #define YY_INPUT(buf,result,max_size)                                   \
51    {                                                                    \
52      int ci;                                                            \
53      if ((ci = rec_sex_parser_getc ((rec_sex_parser_t) yyextra)) == -1)     \
54        {                                                                \
55          result = YY_NULL;                                              \
56        }                                                                \
57      else                                                               \
58        {                                                                \
59          buf[0] = (char) ci;                                            \
60          result = 1;                                                    \
61      }                                                                  \
62    }
64    /* Forward prototypes for functions defined below.  */
65    char *rec_sex_lex_extract_name (char *str);
66    char *rec_sex_lex_extract_subname (char *str);
67    bool rec_sex_lex_extract_index (char *str, int *num);
71 NEWLINE            \n
72 BLANK              [ \t\n]
73 DIGIT              [0-9]
74 LETTER             [a-zA-Z]
75 FIELD_NAME         {LETTER}[a-zA-Z0-9_]*
76 STRING             '([^']|\\(.|\n))*'|\"([^"]|\\(.|\n))*\"
78 /* Please do not touch this comment' */
82 {BLANK}  { /* Ignore whitespace */ }
84 "-"?{DIGIT}*\.{DIGIT}+ {
85   /*
86    * Create a real node.
87    */
88   double real_value;
89   
90   yylval->node = rec_sex_ast_node_new ();
91   rec_atod (yytext, &real_value);
92   rec_sex_ast_node_set_real (yylval->node, real_value);
94   return REC_SEX_TOK_REAL;
97 "-"?((0x[0-9a-fA-F]+)|{DIGIT}+) {
98   /*
99    * Create an integer node.
100    */
101   int integer_value;
103   yylval->node = rec_sex_ast_node_new ();
104   rec_atoi (yytext, &integer_value);
105   rec_sex_ast_node_set_int (yylval->node, integer_value);
107   return REC_SEX_TOK_INT;    
110 "+"      { return REC_SEX_TOK_ADD; }
111 "-"      { return REC_SEX_TOK_SUB; }
112 "/"      { return REC_SEX_TOK_DIV; }
113 "%"      { return REC_SEX_TOK_MOD; }
114 ">>"     { return REC_SEX_TOK_AFTER; }
115 "<<"     { return REC_SEX_TOK_BEFORE; }
116 "<="     { return REC_SEX_TOK_LTE; }
117 ">="     { return REC_SEX_TOK_GTE; }
118 "=="     { return REC_SEX_TOK_SAMETIME; }
119 "=>"     { return REC_SEX_TOK_IMPLIES; }
120 "*"      { return REC_SEX_TOK_MUL; }
121 "="      { return REC_SEX_TOK_EQL; }
122 "!="     { return REC_SEX_TOK_NEQ; }
123 "!"      { return REC_SEX_TOK_NOT; }
124 "~"      { return REC_SEX_TOK_MAT; }
125 ">"      { return REC_SEX_TOK_GT; }
126 "<"      { return REC_SEX_TOK_LT; }
127 "("      { return REC_SEX_TOK_BP; }
128 ")"      { return REC_SEX_TOK_EP; }
129 "&&"     { return REC_SEX_TOK_AND; }
130 "||"     { return REC_SEX_TOK_OR; }
131 "#"      { return REC_SEX_TOK_SHARP; }
132 "?"      { return REC_SEX_TOK_QM; }
133 ":"      { return REC_SEX_TOK_COLON; }
134 "&"      { return REC_SEX_TOK_AMP; }
136 {FIELD_NAME}(\.{FIELD_NAME})?(\[[0-9]+\])? {
137   int res;
138   char *match;
139   char *name, *subname;
140   int index = -1;
142   match = strdup (yytext);
143   rec_sex_lex_extract_index (match, &index);
144   name = rec_sex_lex_extract_name (match);
145   subname = rec_sex_lex_extract_subname (match);
147   /* Create a name node.  */
148   yylval->node = rec_sex_ast_node_new ();
149   rec_sex_ast_node_set_name (yylval->node, name, subname);
150   rec_sex_ast_node_set_index (yylval->node, index);
151   res = REC_SEX_TOK_NAM;
153   free (name);
154   free (match);
156   return res;
159 {STRING} {
160   /*
161    * Create a string node.
162    */
163   
164   /* Strip the quoting characters */
165   yytext[strlen(yytext) - 1] = 0;
167   yylval->node = rec_sex_ast_node_new ();
168   rec_sex_ast_node_set_str (yylval->node, yytext + 1);
170   return REC_SEX_TOK_STR;
173 .        { return REC_SEX_TOK_ERR; }
177 char *
178 rec_sex_lex_extract_name (char *str)
180   size_t size;
181   char *res;
182   char *p;
184   p = str;
185   while ((*p != '[') && (*p != '.') && (*p != 0))
186     {
187       p++;
188     }
190   size = p - str;
191   res = malloc (size + 1);
192   memcpy (res, str, size);
193   res[size] = 0;
195   return res;
198 char *
199 rec_sex_lex_extract_subname (char *str)
201   char *p;
203   /* If there is not a subname denoted in STR then this function
204      returns NULL.  */
205   
206   p = str;
207   while ((*p != '.') && (*p != '\0'))
208     {
209       p++;
210     }
212   if (*p == '\0')
213     {
214       /* There is not a second name.  */
215       return NULL;
216     }
218   p++;  /* Skip the dot separator.  */
220   return rec_sex_lex_extract_name (p);
223 bool
224 rec_sex_lex_extract_index (char *str,
225                            int *num)
227   bool res;
228   char *p;
229   char aux[100];
230   int aux_size;
232   /* Note that this function assumes syntax correctness in STR if a
233      '[' is found.  */  
235   aux_size = 0;
236   p = str;
237   while ((*p != 0) && (*p != '['))
238     {
239       p++;
240     }
242   if (*p == 0)
243     {
244       res = false;
245     }
246   else
247     {
248       p++; /* Pass the [.  */
249       while (*p != ']')
250         {
251           aux[aux_size++] = *p;
252           p++;
253         }
254       aux[aux_size] = 0;
256       if (!rec_atoi (aux, num))
257         {
258           res = false;
259         }
261       res = true;
262     }
264   return res;
267 /* End of rec-sex.l */