diff options
Diffstat (limited to 'lib/forlanlex.l')
-rw-r--r-- | lib/forlanlex.l | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/lib/forlanlex.l b/lib/forlanlex.l new file mode 100644 index 0000000..99966ed --- /dev/null +++ b/lib/forlanlex.l | |||
@@ -0,0 +1,137 @@ | |||
1 | %{ | ||
2 | /* This file is part of Eclat. | ||
3 | Copyright (C) 2012 Sergey Poznyakoff. | ||
4 | |||
5 | Eclat is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 3, or (at your option) | ||
8 | any later version. | ||
9 | |||
10 | Eclat is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with Eclat. If not, see <http://www.gnu.org/licenses/>. */ | ||
17 | |||
18 | #include "libeclat.h" | ||
19 | #include <grecs.h> | ||
20 | #include <grecs-locus.h> | ||
21 | #include "forlangrm.h" | ||
22 | #include "forlan.h" | ||
23 | |||
24 | static const char *forlan_input_base; | ||
25 | static size_t forlan_input_len; | ||
26 | static size_t forlan_input_pos; | ||
27 | |||
28 | #undef YY_INPUT | ||
29 | #define YY_INPUT(buf,result,max_size) \ | ||
30 | do { \ | ||
31 | size_t __s = forlan_input_len - forlan_input_pos; \ | ||
32 | if (__s > max_size) \ | ||
33 | __s = max_size; \ | ||
34 | if (__s > 0) { \ | ||
35 | memcpy(buf, forlan_input_base, __s); \ | ||
36 | forlan_input_pos += __s; \ | ||
37 | } \ | ||
38 | result = __s; \ | ||
39 | } while(0) | ||
40 | |||
41 | #define YY_USER_ACTION do { \ | ||
42 | if (YYSTATE == 0) { \ | ||
43 | yylloc.beg = grecs_current_locus_point; \ | ||
44 | yylloc.beg.col++; \ | ||
45 | } \ | ||
46 | grecs_current_locus_point.col += yyleng; \ | ||
47 | yylloc.end = grecs_current_locus_point; \ | ||
48 | } while (0); | ||
49 | |||
50 | static int yywrap(void); | ||
51 | |||
52 | %} | ||
53 | |||
54 | WS [ \t\f][ \t\f]* | ||
55 | IDC [a-zA-Z_0-9-] | ||
56 | %x COMMENT ML STR | ||
57 | %% | ||
58 | /* Comments */ | ||
59 | "/*" BEGIN(COMMENT); | ||
60 | <COMMENT>[^*\n]* /* eat anything that's not a '*' */ | ||
61 | <COMMENT>"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */ | ||
62 | <COMMENT>\n grecs_locus_point_advance_line(grecs_current_locus_point); | ||
63 | <COMMENT>"*"+"/" BEGIN(INITIAL); | ||
64 | "//".* ; | ||
65 | /* Keywords */ | ||
66 | if return IF; | ||
67 | else return ELSE; | ||
68 | last return LAST; | ||
69 | ! return NOT; | ||
70 | "&&" return AND; | ||
71 | "||" return OR; | ||
72 | {IDC}{IDC}* { grecs_line_begin(); | ||
73 | grecs_line_add(yytext, yyleng); | ||
74 | yylval.string = grecs_line_finish(); | ||
75 | return IDENT; } | ||
76 | /* Quoted strings */ | ||
77 | \"[^\\"\n]*\" { grecs_line_begin(); | ||
78 | grecs_line_add(yytext + 1, yyleng - 2); | ||
79 | yylval.string = grecs_line_finish(); | ||
80 | return STRING; } | ||
81 | \"[^\\"\n]*\\\n { BEGIN(STR); | ||
82 | grecs_line_begin(); | ||
83 | grecs_line_acc_grow_unescape_last(yytext + 1, | ||
84 | yyleng - 1); | ||
85 | grecs_locus_point_advance_line(grecs_current_locus_point); } | ||
86 | \"[^\\"\n]*\\. { BEGIN(STR); | ||
87 | grecs_line_begin(); | ||
88 | grecs_line_acc_grow_unescape_last(yytext + 1, | ||
89 | yyleng - 1); } | ||
90 | <STR>\"[^\\"\n]*\\\n { grecs_line_acc_grow_unescape_last(yytext, yyleng); | ||
91 | grecs_locus_point_advance_line(grecs_current_locus_point); } | ||
92 | <STR>[^\\"\n]*\\. { grecs_line_acc_grow_unescape_last(yytext, yyleng); } | ||
93 | <STR>[^\\"\n]*\" { BEGIN(INITIAL); | ||
94 | if (yyleng > 1) | ||
95 | grecs_line_add(yytext, yyleng - 1); | ||
96 | yylval.string = grecs_line_finish(); | ||
97 | return STRING; } | ||
98 | /* Other tokens */ | ||
99 | {WS} ; | ||
100 | \n { grecs_locus_point_advance_line(grecs_current_locus_point); } | ||
101 | [.,;{}()\[\]] return yytext[0]; | ||
102 | . { if (isascii(yytext[0]) && isprint(yytext[0])) | ||
103 | grecs_error(&yylloc, 0, | ||
104 | _("stray character %c"), yytext[0]); | ||
105 | else | ||
106 | grecs_error(&yylloc, 0, | ||
107 | _("stray character \\%03o"), | ||
108 | (unsigned char) yytext[0]); } | ||
109 | %% | ||
110 | |||
111 | static int | ||
112 | yywrap() | ||
113 | { | ||
114 | return 1; | ||
115 | } | ||
116 | |||
117 | void | ||
118 | forlan_lex_begin(const char *input, size_t length, | ||
119 | struct grecs_locus_point *pt) | ||
120 | { | ||
121 | forlan_input_base = input; | ||
122 | forlan_input_len = length; | ||
123 | grecs_current_locus_point = *pt; | ||
124 | yy_flex_debug = debug_level(forlan_dbg) >= FORLAN_DBG_LEX; | ||
125 | grecs_line_acc_create(); | ||
126 | } | ||
127 | |||
128 | void | ||
129 | forlan_lex_end() | ||
130 | { | ||
131 | grecs_line_acc_free(); | ||
132 | } | ||
133 | |||
134 | |||
135 | |||
136 | |||
137 | |||