diff options
Diffstat (limited to 'src/meta1-lex.l')
-rw-r--r-- | src/meta1-lex.l | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/src/meta1-lex.l b/src/meta1-lex.l new file mode 100644 index 0000000..cb2931d --- /dev/null +++ b/src/meta1-lex.l | |||
@@ -0,0 +1,114 @@ | |||
1 | /* MeTA1 configuration lexer for Grecs. -*- c -*- */ | ||
2 | %top { | ||
3 | /* MeTA1 configuration lexer for Grecs. | ||
4 | Copyright (C) 2007-2011 Sergey Poznyakoff | ||
5 | |||
6 | Grecs is free software; you can redistribute it and/or modify it | ||
7 | under the terms of the GNU General Public License as published by the | ||
8 | Free Software Foundation; either version 3 of the License, or (at your | ||
9 | option) any later version. | ||
10 | |||
11 | Grecs 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 along | ||
17 | with Grecs. If not, see <http://www.gnu.org/licenses/>. */ | ||
18 | |||
19 | /* This file implements a lexical analyzer for MeTA1 main configuration file. | ||
20 | */ | ||
21 | |||
22 | #ifndef HAVE_CONFIG_H | ||
23 | # include <config.h> | ||
24 | #endif | ||
25 | #include "grecs.h" | ||
26 | #include "meta1-gram.h" | ||
27 | #include <ctype.h> | ||
28 | } | ||
29 | |||
30 | %{ | ||
31 | static int yywrap(void); | ||
32 | static void meta1_line_add_unescape_hex(const char *text, size_t len); | ||
33 | %} | ||
34 | |||
35 | %x COMMENT STR | ||
36 | X [0-9a-fA-F] | ||
37 | %% | ||
38 | /* C-style comments */ | ||
39 | "/*" BEGIN (COMMENT); | ||
40 | <COMMENT>[^*\n]* /* eat anything that's not a '*' */ | ||
41 | <COMMENT>"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */ | ||
42 | <COMMENT>\n ++grecs_current_locus.line; | ||
43 | <COMMENT>"*"+"/" BEGIN (INITIAL); | ||
44 | /* End-of-line comments */ | ||
45 | #.*\n { grecs_current_locus.line++; } | ||
46 | #.* /* end-of-file comment */; | ||
47 | /* Number */ | ||
48 | 0[xX]{X}+ | | ||
49 | 0[0-7]+ | | ||
50 | [1-9][0-9]+ { grecs_line_begin(); | ||
51 | grecs_line_add(yytext, yyleng); | ||
52 | yylval.string = grecs_line_finish(); | ||
53 | return META1_STRING; } | ||
54 | /* Identifiers (unquoted strings) */ | ||
55 | [a-zA-Z0-9_\./:\*-]+ { grecs_line_begin(); | ||
56 | grecs_line_add(yytext, yyleng); | ||
57 | yylval.ident.locus = grecs_current_locus; | ||
58 | yylval.ident.string = grecs_line_finish(); | ||
59 | return META1_IDENT; } | ||
60 | /* Quoted strings */ | ||
61 | \"[^\\"\n]*\" { grecs_line_begin(); | ||
62 | grecs_line_add(yytext + 1, yyleng - 2); | ||
63 | yylval.string = grecs_line_finish(); | ||
64 | return META1_STRING; } | ||
65 | \"[^\\"\n]*\\x{X}{1,2} { BEGIN(STR); | ||
66 | grecs_line_begin(); | ||
67 | meta1_line_add_unescape_hex(yytext + 1, yyleng - 1); | ||
68 | } | ||
69 | \"[^\\"\n]*\\. { BEGIN(STR); | ||
70 | grecs_line_begin(); | ||
71 | grecs_line_acc_grow_unescape_last(yytext + 1, | ||
72 | yyleng - 1); } | ||
73 | <STR>[^\\"\n]*\\x{X}{1,2} { meta1_line_add_unescape_hex(yytext, yyleng); } | ||
74 | <STR>[^\\"\n]*\\. { grecs_line_acc_grow_unescape_last(yytext, yyleng); } | ||
75 | <STR>[^\\"\n]*\" { BEGIN(INITIAL); | ||
76 | if (yyleng > 1) | ||
77 | grecs_line_add(yytext, yyleng - 1); | ||
78 | yylval.string = grecs_line_finish(); | ||
79 | return META1_STRING; } | ||
80 | <STR>[^\\"\n]*\n { BEGIN(INITIAL); | ||
81 | grecs_error(&grecs_current_locus, 0, | ||
82 | _("newline in a string")); | ||
83 | grecs_line_add (yytext, yyleng - 1); | ||
84 | yylval.string = grecs_line_finish (); | ||
85 | return META1_STRING; } | ||
86 | /* Other tokens */ | ||
87 | [ \t\f][ \t\f]* ; | ||
88 | \n { grecs_current_locus.line++; } | ||
89 | [,;{}=] return yytext[0]; | ||
90 | . { grecs_error(&grecs_current_locus, 0, | ||
91 | (isascii(yytext[0]) && isprint(yytext[0])) ? | ||
92 | _("stray character %c") : | ||
93 | _("stray character \\%03o"), | ||
94 | (unsigned char) yytext[0]); } | ||
95 | %% | ||
96 | |||
97 | int | ||
98 | yywrap() | ||
99 | { | ||
100 | return 1; | ||
101 | } | ||
102 | |||
103 | static void | ||
104 | meta1_line_add_unescape_hex(const char *text, size_t len) | ||
105 | { | ||
106 | for (; text[len-1] != 'x' && len > 0; len--) | ||
107 | ; | ||
108 | grecs_line_acc_grow(text, len - 2); | ||
109 | grecs_line_acc_grow_char((char) strtoul (text + len, NULL, 16)); | ||
110 | } | ||
111 | |||
112 | |||
113 | |||
114 | |||