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