Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1901 serge 1
%{
2
/*
3
 * Copyright © 2010 Intel Corporation
4
 *
5
 * Permission is hereby granted, free of charge, to any person obtaining a
6
 * copy of this software and associated documentation files (the "Software"),
7
 * to deal in the Software without restriction, including without limitation
8
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
 * and/or sell copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following conditions:
11
 *
12
 * The above copyright notice and this permission notice (including the next
13
 * paragraph) shall be included in all copies or substantial portions of the
14
 * Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
 * DEALINGS IN THE SOFTWARE.
23
 */
24
 
25
#include 
26
#include 
27
#include 
28
 
29
#include "glcpp.h"
30
#include "glcpp-parse.h"
31
 
32
/* Flex annoyingly generates some functions without making them
33
 * static. Let's declare them here. */
34
int glcpp_get_column  (yyscan_t yyscanner);
35
void glcpp_set_column (int  column_no , yyscan_t yyscanner);
36
 
37
#define YY_NO_INPUT
38
 
39
#define YY_USER_ACTION                                          \
40
   do {                                                         \
41
      yylloc->first_column = yycolumn + 1;                      \
42
      yylloc->first_line = yylineno;                            \
43
      yycolumn += yyleng;                                       \
44
   } while(0);
45
 
46
#define YY_USER_INIT			\
47
	do {				\
48
		yylineno = 1;		\
49
		yycolumn = 1;		\
50
		yylloc->source = 0;	\
51
	} while(0)
52
%}
53
 
54
%option bison-bridge bison-locations reentrant noyywrap
55
%option extra-type="glcpp_parser_t *"
56
%option prefix="glcpp_"
57
%option stack
58
%option never-interactive
59
 
60
%x DONE COMMENT UNREACHABLE
61
 
62
SPACE		[[:space:]]
63
NONSPACE	[^[:space:]]
64
NEWLINE		[\n]
65
HSPACE		[ \t]
66
HASH		^{HSPACE}*#{HSPACE}*
67
IDENTIFIER	[_a-zA-Z][_a-zA-Z0-9]*
68
PUNCTUATION	[][(){}.&*~!/%<>^|;,=+-]
69
OTHER		[^][(){}.&*~!/%<>^|;,=#[:space:]+-]+
70
 
71
DIGITS			[0-9][0-9]*
72
DECIMAL_INTEGER		[1-9][0-9]*[uU]?
73
OCTAL_INTEGER		0[0-7]*[uU]?
74
HEXADECIMAL_INTEGER	0[xX][0-9a-fA-F]+[uU]?
75
 
76
%%
77
 
78
	/* Single-line comments */
79
"//"[^\n]* {
80
}
81
 
82
	/* Multi-line comments */
83
"/*"                    { yy_push_state(COMMENT, yyscanner); }
84
[^*\n]*
85
[^*\n]*\n      { yylineno++; yycolumn = 0; return NEWLINE; }
86
"*"+[^*/\n]*
87
"*"+[^*/\n]*\n { yylineno++; yycolumn = 0; return NEWLINE; }
88
"*"+"/"        {
89
	yy_pop_state(yyscanner);
90
	if (yyextra->space_tokens)
91
		return SPACE;
92
}
93
 
94
{HASH}version {
95
	yylval->str = ralloc_strdup (yyextra, yytext);
96
	yyextra->space_tokens = 0;
97
	return HASH_VERSION;
98
}
99
 
100
	/* glcpp doesn't handle #extension, #version, or #pragma directives.
101
	 * Simply pass them through to the main compiler's lexer/parser. */
102
{HASH}(extension|pragma)[^\n]+ {
103
	yylval->str = ralloc_strdup (yyextra, yytext);
104
	yylineno++;
105
	yycolumn = 0;
106
	return OTHER;
107
}
108
 
109
{HASH}line{HSPACE}+{DIGITS}{HSPACE}+{DIGITS}{HSPACE}*$ {
110
	/* Eat characters until the first digit is
111
	 * encountered
112
	 */
113
	char *ptr = yytext;
114
	while (!isdigit(*ptr))
115
		ptr++;
116
 
117
	/* Subtract one from the line number because
118
	 * yylineno is zero-based instead of
119
	 * one-based.
120
	 */
121
	yylineno = strtol(ptr, &ptr, 0) - 1;
122
	yylloc->source = strtol(ptr, NULL, 0);
123
}
124
 
125
{HASH}line{HSPACE}+{DIGITS}{HSPACE}*$ {
126
	/* Eat characters until the first digit is
127
	 * encountered
128
	 */
129
	char *ptr = yytext;
130
	while (!isdigit(*ptr))
131
		ptr++;
132
 
133
	/* Subtract one from the line number because
134
	 * yylineno is zero-based instead of
135
	 * one-based.
136
	 */
137
	yylineno = strtol(ptr, &ptr, 0) - 1;
138
}
139
 
140
{HASH}ifdef/.*\n {
141
	yyextra->lexing_if = 1;
142
	yyextra->space_tokens = 0;
143
	return HASH_IFDEF;
144
}
145
 
146
{HASH}ifndef/.*\n {
147
	yyextra->lexing_if = 1;
148
	yyextra->space_tokens = 0;
149
	return HASH_IFNDEF;
150
}
151
 
152
{HASH}if/[^_a-zA-Z0-9].*\n {
153
	yyextra->lexing_if = 1;
154
	yyextra->space_tokens = 0;
155
	return HASH_IF;
156
}
157
 
158
{HASH}elif/.*\n {
159
	yyextra->lexing_if = 1;
160
	yyextra->space_tokens = 0;
161
	return HASH_ELIF;
162
}
163
 
164
{HASH}else/.*\n {
165
	yyextra->space_tokens = 0;
166
	return HASH_ELSE;
167
}
168
 
169
{HASH}endif/.*\n {
170
	yyextra->space_tokens = 0;
171
	return HASH_ENDIF;
172
}
173
 
174
	/* When skipping (due to an #if 0 or similar) consume anything
175
	 * up to a newline. We do this with less priority than any
176
	 * #if-related directive (#if, #elif, #else, #endif), but with
177
	 * more priority than any other directive or token to avoid
178
	 * any side-effects from skipped content.
179
	 *
180
	 * We use the lexing_if flag to avoid skipping any part of an
181
	 * if conditional expression. */
182
[^\n]+/\n {
183
	/* Since this rule always matches, YY_USER_ACTION gets called for it,
184
	 * wrongly incrementing yycolumn.  We undo that effect here. */
185
	yycolumn -= yyleng;
186
	if (yyextra->lexing_if ||
187
	    yyextra->skip_stack == NULL ||
188
	    yyextra->skip_stack->type == SKIP_NO_SKIP)
189
	{
190
		REJECT;
191
	}
192
}
193
 
194
{HASH}error.* {
195
	char *p;
196
	for (p = yytext; !isalpha(p[0]); p++); /* skip "  #   " */
197
	p += 5; /* skip "error" */
198
	glcpp_error(yylloc, yyextra, "#error%s", p);
199
}
200
 
201
{HASH}define{HSPACE}+/{IDENTIFIER}"(" {
202
	yyextra->space_tokens = 0;
203
	return HASH_DEFINE_FUNC;
204
}
205
 
206
{HASH}define {
207
	yyextra->space_tokens = 0;
208
	return HASH_DEFINE_OBJ;
209
}
210
 
211
{HASH}undef {
212
	yyextra->space_tokens = 0;
213
	return HASH_UNDEF;
214
}
215
 
216
{HASH} {
217
	yyextra->space_tokens = 0;
218
	return HASH;
219
}
220
 
221
{DECIMAL_INTEGER} {
222
	yylval->str = ralloc_strdup (yyextra, yytext);
223
	return INTEGER_STRING;
224
}
225
 
226
{OCTAL_INTEGER} {
227
	yylval->str = ralloc_strdup (yyextra, yytext);
228
	return INTEGER_STRING;
229
}
230
 
231
{HEXADECIMAL_INTEGER} {
232
	yylval->str = ralloc_strdup (yyextra, yytext);
233
	return INTEGER_STRING;
234
}
235
 
236
"<<"  {
237
	return LEFT_SHIFT;
238
}
239
 
240
">>" {
241
	return RIGHT_SHIFT;
242
}
243
 
244
"<=" {
245
	return LESS_OR_EQUAL;
246
}
247
 
248
">=" {
249
	return GREATER_OR_EQUAL;
250
}
251
 
252
"==" {
253
	return EQUAL;
254
}
255
 
256
"!=" {
257
	return NOT_EQUAL;
258
}
259
 
260
"&&" {
261
	return AND;
262
}
263
 
264
"||" {
265
	return OR;
266
}
267
 
268
"##" {
269
	return PASTE;
270
}
271
 
272
"defined" {
273
	return DEFINED;
274
}
275
 
276
{IDENTIFIER} {
277
	yylval->str = ralloc_strdup (yyextra, yytext);
278
	return IDENTIFIER;
279
}
280
 
281
{PUNCTUATION} {
282
	return yytext[0];
283
}
284
 
285
{OTHER}+ {
286
	yylval->str = ralloc_strdup (yyextra, yytext);
287
	return OTHER;
288
}
289
 
290
{HSPACE}+ {
291
	if (yyextra->space_tokens) {
292
		return SPACE;
293
	}
294
}
295
 
296
\n {
297
	yyextra->lexing_if = 0;
298
	yylineno++;
299
	yycolumn = 0;
300
	return NEWLINE;
301
}
302
 
303
	/* Handle missing newline at EOF. */
304
<> {
305
	BEGIN DONE; /* Don't keep matching this rule forever. */
306
	yyextra->lexing_if = 0;
307
	return NEWLINE;
308
}
309
 
310
	/* We don't actually use the UNREACHABLE start condition. We
311
	only have this action here so that we can pretend to call some
312
	generated functions, (to avoid "defined but not used"
313
	warnings. */
314
. {
315
	unput('.');
316
	yy_top_state(yyextra);
317
}
318
 
319
%%
320
 
321
void
322
glcpp_lex_set_source_string(glcpp_parser_t *parser, const char *shader)
323
{
324
	yy_scan_string(shader, parser->scanner);
325
}