1 /* MeTA1 configuration lexer for Grecs. -*- c -*- */
2 %option noinput
3 %option nounput
4 %top {
5 /* MeTA1 configuration lexer for Grecs.
6    Copyright (C) 2007-2016 Sergey Poznyakoff
7 
8    Grecs is free software; you can redistribute it and/or modify it
9    under the terms of the GNU General Public License as published by the
10    Free Software Foundation; either version 3 of the License, or (at your
11    option) any later version.
12 
13    Grecs is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License along
19    with Grecs. If not, see <http://www.gnu.org/licenses/>. */
20 
21 /* This file implements a lexical analyzer for MeTA1 main configuration file.
22  */
23 
24 #ifdef HAVE_CONFIG_H
25 # include <config.h>
26 #endif
27 #include "grecs.h"
28 #include "meta1-gram.h"
29 #include <ctype.h>
30 }
31 
32 %{
33 static int yywrap(void);
34 static void meta1_line_add_unescape_hex(const char *text, size_t len);
35 
36 #define YY_USER_ACTION do {						\
37 		if (YYSTATE == 0) {					\
38 			yylloc.beg = grecs_current_locus_point;		\
39 			yylloc.beg.col++;				\
40 		}							\
41   		grecs_current_locus_point.col += yyleng;		\
42  		yylloc.end = grecs_current_locus_point;			\
43    	} while (0);
44 %}
45 
46 %x COMMENT STR
47 X [0-9a-fA-F]
48 %%
49          /* C-style comments */
50 "/*"                    BEGIN (COMMENT);
51 <COMMENT>[^*\n]*        /* eat anything that's not a '*' */
52 <COMMENT>"*"+[^*/\n]*   /* eat up '*'s not followed by '/'s */
53 <COMMENT>\n             grecs_locus_point_advance_line(grecs_current_locus_point);
54 <COMMENT>"*"+"/"        BEGIN (INITIAL);
55          /* End-of-line comments */
56 #.*\n     { grecs_locus_point_advance_line(grecs_current_locus_point); }
57 #.*       /* end-of-file comment */;
58          /* Number */
59 0[xX]{X}+ |
60 0[0-7]+ |
61 [1-9][0-9]+             { grecs_line_begin();
62 	                  grecs_line_add(yytext, yyleng);
63 	                  yylval.string = grecs_line_finish();
64                           return META1_STRING; }
65         /* Identifiers (unquoted strings) */
66 [a-zA-Z0-9_\./:\*-]+    { grecs_line_begin();
67 	                  grecs_line_add(yytext, yyleng);
68 	                  yylval.string = grecs_line_finish();
69                           return META1_IDENT; }
70          /* Quoted strings */
71 \"[^\\"\n]*\"           { grecs_line_begin();
72 	                  grecs_line_add(yytext + 1, yyleng - 2);
73 	                  yylval.string = grecs_line_finish();
74                           return META1_STRING; }
75 \"[^\\"\n]*\\x{X}{1,2}  { BEGIN(STR);
76                           grecs_line_begin();
77 			  meta1_line_add_unescape_hex(yytext + 1, yyleng - 1);
78 		        }
79 \"[^\\"\n]*\\.          { BEGIN(STR);
80 	                  grecs_line_begin();
81 			  grecs_line_acc_grow_unescape_last(yytext + 1,
82                                                             yyleng - 1,
83                                                             &yylloc); }
84 <STR>[^\\"\n]*\\x{X}{1,2} { meta1_line_add_unescape_hex(yytext, yyleng); }
85 <STR>[^\\"\n]*\\.       { grecs_line_acc_grow_unescape_last(yytext, yyleng,
86                                                             &yylloc); }
87 <STR>[^\\"\n]*\"        { BEGIN(INITIAL);
88                           if (yyleng > 1)
89                             grecs_line_add(yytext, yyleng - 1);
90                           yylval.string = grecs_line_finish();
91 		          return META1_STRING; }
92 <STR>[^\\"\n]*\n        { BEGIN(INITIAL);
93                           grecs_error(&yylloc, 0,
94                                       _("newline in a string"));
95                           grecs_line_add(yytext, yyleng - 1);
96                           yylval.string = grecs_line_finish();
97                           return META1_STRING; }
98          /* Other tokens */
99 [ \t\f][ \t\f]*         ;
100 \n                      { grecs_locus_point_advance_line(grecs_current_locus_point); }
101 [,;{}=]                 return yytext[0];
102 .        { grecs_error(&yylloc, 0,
103                        (isascii(yytext[0]) && isprint(yytext[0])) ?
104                           _("stray character %c") :
105                           _("stray character \\%03o"),
106 			         (unsigned char) yytext[0]); }
107 %%
108 
109 int
110 yywrap()
111 {
112         return 1;
113 }
114 
115 static void
meta1_line_add_unescape_hex(const char * text,size_t len)116 meta1_line_add_unescape_hex(const char *text, size_t len)
117 {
118         for (; text[len-1] != 'x' && len > 0; len--)
119 		;
120 	grecs_line_acc_grow(text, len - 2);
121 	grecs_line_acc_grow_char((char) strtoul (text + len, NULL, 16));
122 }
123 
124 
125 
126 
127