Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
4358 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
#ifdef _MSC_VER
38
#define YY_NO_UNISTD_H
39
#endif
40
 
41
#define YY_NO_INPUT
42
 
43
#define YY_USER_ACTION							\
44
	do {								\
45
		if (parser->has_new_line_number)			\
46
			yylineno = parser->new_line_number;		\
47
		if (parser->has_new_source_number)			\
48
			yylloc->source = parser->new_source_number;	\
49
		yylloc->first_column = yycolumn + 1;			\
50
		yylloc->first_line = yylineno;				\
51
		yycolumn += yyleng;					\
52
		parser->has_new_line_number = 0;			\
53
		parser->has_new_source_number = 0;			\
54
 } while(0);
55
 
56
#define YY_USER_INIT			\
57
	do {				\
58
		yylineno = 1;		\
59
		yycolumn = 1;		\
60
		yylloc->source = 0;	\
61
	} while(0)
62
%}
63
 
64
%option bison-bridge bison-locations reentrant noyywrap
65
%option extra-type="glcpp_parser_t *"
66
%option prefix="glcpp_"
67
%option stack
68
%option never-interactive
69
 
70
%x DONE COMMENT UNREACHABLE SKIP DEFINE
71
 
72
SPACE		[[:space:]]
73
NONSPACE	[^[:space:]]
74
NEWLINE		[\n]
75
HSPACE		[ \t]
76
HASH		^{HSPACE}*#{HSPACE}*
77
IDENTIFIER	[_a-zA-Z][_a-zA-Z0-9]*
78
PUNCTUATION	[][(){}.&*~!/%<>^|;,=+-]
79
 
80
/* The OTHER class is simply a catch-all for things that the CPP
81
parser just doesn't care about. Since flex regular expressions that
82
match longer strings take priority over those matching shorter
83
strings, we have to be careful to avoid OTHER matching and hiding
84
something that CPP does care about. So we simply exclude all
85
characters that appear in any other expressions. */
86
 
87
OTHER		[^][_#[:space:]#a-zA-Z0-9(){}.&*~!/%<>^|;,=+-]
88
 
89
DIGITS			[0-9][0-9]*
90
DECIMAL_INTEGER		[1-9][0-9]*[uU]?
91
OCTAL_INTEGER		0[0-7]*[uU]?
92
HEXADECIMAL_INTEGER	0[xX][0-9a-fA-F]+[uU]?
93
 
94
%%
95
	/* Implicitly switch between SKIP and INITIAL (non-skipping);
96
	 * don't switch if some other state was explicitly set.
97
	 */
98
	glcpp_parser_t *parser = yyextra;
99
	if (YY_START == 0 || YY_START == SKIP) {
100
		if (parser->lexing_if || parser->skip_stack == NULL || parser->skip_stack->type == SKIP_NO_SKIP) {
101
			BEGIN 0;
102
		} else {
103
			BEGIN SKIP;
104
		}
105
	}
106
 
107
	/* Single-line comments */
108
"//"[^\n]* {
109
}
110
 
111
	/* Multi-line comments */
112
"/*"                    { yy_push_state(COMMENT, yyscanner); }
113
[^*\n]*
114
[^*\n]*\n      { yylineno++; yycolumn = 0; return NEWLINE; }
115
"*"+[^*/\n]*
116
"*"+[^*/\n]*\n { yylineno++; yycolumn = 0; return NEWLINE; }
117
"*"+"/"        {
118
	yy_pop_state(yyscanner);
119
	if (yyextra->space_tokens)
120
		return SPACE;
121
}
122
 
123
{HASH}version{HSPACE}+ {
124
	yylval->str = ralloc_strdup (yyextra, yytext);
125
	yyextra->space_tokens = 0;
126
	return HASH_VERSION;
127
}
128
 
129
	/* glcpp doesn't handle #extension, #version, or #pragma directives.
130
	 * Simply pass them through to the main compiler's lexer/parser. */
131
{HASH}(extension|pragma)[^\n]+ {
132
	yylval->str = ralloc_strdup (yyextra, yytext);
133
	yylineno++;
134
	yycolumn = 0;
135
	return OTHER;
136
}
137
 
138
{HASH}line{HSPACE}+ {
139
	return HASH_LINE;
140
}
141
 
142
{
143
{HASH}ifdef {
144
	yyextra->lexing_if = 1;
145
	yyextra->space_tokens = 0;
146
	return HASH_IFDEF;
147
}
148
 
149
{HASH}ifndef {
150
	yyextra->lexing_if = 1;
151
	yyextra->space_tokens = 0;
152
	return HASH_IFNDEF;
153
}
154
 
155
{HASH}if/[^_a-zA-Z0-9] {
156
	yyextra->lexing_if = 1;
157
	yyextra->space_tokens = 0;
158
	return HASH_IF;
159
}
160
 
161
{HASH}elif/[^_a-zA-Z0-9] {
162
	yyextra->lexing_if = 1;
163
	yyextra->space_tokens = 0;
164
	return HASH_ELIF;
165
}
166
 
167
{HASH}else {
168
	yyextra->space_tokens = 0;
169
	return HASH_ELSE;
170
}
171
 
172
{HASH}endif {
173
	yyextra->space_tokens = 0;
174
	return HASH_ENDIF;
175
}
176
}
177
 
178
[^\n] ;
179
 
180
{HASH}error.* {
181
	char *p;
182
	for (p = yytext; !isalpha(p[0]); p++); /* skip "  #   " */
183
	p += 5; /* skip "error" */
184
	glcpp_error(yylloc, yyextra, "#error%s", p);
185
}
186
 
187
{HASH}define{HSPACE}+ {
188
	yyextra->space_tokens = 0;
189
	yy_push_state(DEFINE, yyscanner);
190
	return HASH_DEFINE;
191
}
192
 
193
{IDENTIFIER}/"(" {
194
	yy_pop_state(yyscanner);
195
	yylval->str = ralloc_strdup (yyextra, yytext);
196
	return FUNC_IDENTIFIER;
197
}
198
 
199
{IDENTIFIER} {
200
	yy_pop_state(yyscanner);
201
	yylval->str = ralloc_strdup (yyextra, yytext);
202
	return OBJ_IDENTIFIER;
203
}
204
 
205
{HASH}undef {
206
	yyextra->space_tokens = 0;
207
	return HASH_UNDEF;
208
}
209
 
210
{HASH} {
211
	yyextra->space_tokens = 0;
212
	return HASH;
213
}
214
 
215
{DECIMAL_INTEGER} {
216
	yylval->str = ralloc_strdup (yyextra, yytext);
217
	return INTEGER_STRING;
218
}
219
 
220
{OCTAL_INTEGER} {
221
	yylval->str = ralloc_strdup (yyextra, yytext);
222
	return INTEGER_STRING;
223
}
224
 
225
{HEXADECIMAL_INTEGER} {
226
	yylval->str = ralloc_strdup (yyextra, yytext);
227
	return INTEGER_STRING;
228
}
229
 
230
"<<"  {
231
	return LEFT_SHIFT;
232
}
233
 
234
">>" {
235
	return RIGHT_SHIFT;
236
}
237
 
238
"<=" {
239
	return LESS_OR_EQUAL;
240
}
241
 
242
">=" {
243
	return GREATER_OR_EQUAL;
244
}
245
 
246
"==" {
247
	return EQUAL;
248
}
249
 
250
"!=" {
251
	return NOT_EQUAL;
252
}
253
 
254
"&&" {
255
	return AND;
256
}
257
 
258
"||" {
259
	return OR;
260
}
261
 
262
"##" {
263
	if (parser->is_gles)
264
		glcpp_error(yylloc, yyextra, "Token pasting (##) is illegal in GLES");
265
	return PASTE;
266
}
267
 
268
"defined" {
269
	return DEFINED;
270
}
271
 
272
{IDENTIFIER} {
273
	yylval->str = ralloc_strdup (yyextra, yytext);
274
	return IDENTIFIER;
275
}
276
 
277
{PUNCTUATION} {
278
	return yytext[0];
279
}
280
 
281
{OTHER}+ {
282
	yylval->str = ralloc_strdup (yyextra, yytext);
283
	return OTHER;
284
}
285
 
286
{HSPACE}+ {
287
	if (yyextra->space_tokens) {
288
		return SPACE;
289
	}
290
}
291
 
292
\n {
293
	yyextra->lexing_if = 0;
294
	yylineno++;
295
	yycolumn = 0;
296
	return NEWLINE;
297
}
298
 
299
	/* Handle missing newline at EOF. */
300
<> {
301
	BEGIN DONE; /* Don't keep matching this rule forever. */
302
	yyextra->lexing_if = 0;
303
	return NEWLINE;
304
}
305
 
306
	/* We don't actually use the UNREACHABLE start condition. We
307
	only have this action here so that we can pretend to call some
308
	generated functions, (to avoid "defined but not used"
309
	warnings. */
310
. {
311
	unput('.');
312
	yy_top_state(yyextra);
313
}
314
 
315
%%
316
 
317
void
318
glcpp_lex_set_source_string(glcpp_parser_t *parser, const char *shader)
319
{
320
	yy_scan_string(shader, parser->scanner);
321
}