ir_to_mesa: Add support for scalar * mat, vec * mat.
[mesa.git] / src / glsl / glcpp / glcpp-lex.l
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 <stdio.h>
26 #include <string.h>
27
28 #include "glcpp.h"
29 #include "glcpp-parse.h"
30
31 #define YY_USER_ACTION \
32 do { \
33 yylloc->source = 0; \
34 yylloc->first_column = yycolumn + 1; \
35 yylloc->first_line = yylineno; \
36 yycolumn += yyleng; \
37 } while(0);
38 %}
39
40 %option bison-bridge bison-locations reentrant noyywrap
41 %option extra-type="glcpp_parser_t *"
42 %option prefix="glcpp_"
43 %option stack
44
45 %x DONE COMMENT
46
47 SPACE [[:space:]]
48 NONSPACE [^[:space:]]
49 NEWLINE [\n]
50 HSPACE [ \t]
51 HASH ^{HSPACE}*#{HSPACE}*
52 IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]*
53 PUNCTUATION [][(){}.&*~!/%<>^|;,=+-]
54 OTHER [^][(){}.&*~!/%<>^|;,=#[:space:]+-]+
55
56 DECIMAL_INTEGER [1-9][0-9]*[uU]?
57 OCTAL_INTEGER 0[0-7]*[uU]?
58 HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]?
59
60 %%
61
62 /* Single-line comments */
63 "//"[^\n]*\n {
64 yylineno++;
65 yycolumn = 0;
66 return NEWLINE;
67 }
68
69 /* Multi-line comments */
70 "/*" { yy_push_state(COMMENT, yyscanner); }
71 <COMMENT>[^*\n]*
72 <COMMENT>[^*\n]*\n { yylineno++; yycolumn = 0; }
73 <COMMENT>"*"+[^*/\n]*
74 <COMMENT>"*"+[^*/\n]*\n { yylineno++; yycolumn = 0; }
75 <COMMENT>"*"+"/" {
76 yy_pop_state(yyscanner);
77 if (yyextra->space_tokens)
78 return SPACE;
79 }
80
81 /* glcpp doesn't handle #extension, #version, or #pragma directives.
82 * Simply pass them through to the main compiler's lexer/parser. */
83 {HASH}(extension|version|pragma)[^\n]+ {
84 yylval->str = xtalloc_strdup (yyextra, yytext);
85 yylineno++;
86 yycolumn = 0;
87 return OTHER;
88 }
89
90 {HASH}ifdef/.*\n {
91 yyextra->space_tokens = 0;
92 return HASH_IFDEF;
93 }
94
95 {HASH}ifndef/.*\n {
96 yyextra->space_tokens = 0;
97 return HASH_IFNDEF;
98 }
99
100 {HASH}if{HSPACE}/.*\n {
101 yyextra->lexing_if = 1;
102 yyextra->space_tokens = 0;
103 return HASH_IF;
104 }
105
106 {HASH}elif/.*\n {
107 yyextra->lexing_if = 1;
108 yyextra->space_tokens = 0;
109 return HASH_ELIF;
110 }
111
112 {HASH}else/.*\n {
113 yyextra->space_tokens = 0;
114 return HASH_ELSE;
115 }
116
117 {HASH}endif/.*\n {
118 yyextra->space_tokens = 0;
119 return HASH_ENDIF;
120 }
121
122 /* When skipping (due to an #if 0 or similar) consume anything
123 * up to a newline. We do this less priroty than any
124 * #if-related directive (#if, #elif, #else, #endif), but with
125 * more priority than any other directive or token to avoid
126 * any side-effects from skipped content.
127 *
128 * We use the lexing_if flag to avoid skipping any part of an
129 * if conditional expression. */
130 [^\n]+/\n {
131 /* Since this rule always matches, YY_USER_ACTION gets called for it,
132 * wrongly incrementing yycolumn. We undo that effect here. */
133 yycolumn -= yyleng;
134 if (yyextra->lexing_if ||
135 yyextra->skip_stack == NULL ||
136 yyextra->skip_stack->type == SKIP_NO_SKIP)
137 {
138 REJECT;
139 }
140 }
141
142 {HASH}define{HSPACE}+/{IDENTIFIER}"(" {
143 yyextra->space_tokens = 0;
144 return HASH_DEFINE_FUNC;
145 }
146
147 {HASH}define {
148 yyextra->space_tokens = 0;
149 return HASH_DEFINE_OBJ;
150 }
151
152 {HASH}undef {
153 yyextra->space_tokens = 0;
154 return HASH_UNDEF;
155 }
156
157 {HASH} {
158 yyextra->space_tokens = 0;
159 return HASH;
160 }
161
162 {DECIMAL_INTEGER} {
163 yylval->str = xtalloc_strdup (yyextra, yytext);
164 return INTEGER_STRING;
165 }
166
167 {OCTAL_INTEGER} {
168 yylval->str = xtalloc_strdup (yyextra, yytext);
169 return INTEGER_STRING;
170 }
171
172 {HEXADECIMAL_INTEGER} {
173 yylval->str = xtalloc_strdup (yyextra, yytext);
174 return INTEGER_STRING;
175 }
176
177 "<<" {
178 return LEFT_SHIFT;
179 }
180
181 ">>" {
182 return RIGHT_SHIFT;
183 }
184
185 "<=" {
186 return LESS_OR_EQUAL;
187 }
188
189 ">=" {
190 return GREATER_OR_EQUAL;
191 }
192
193 "==" {
194 return EQUAL;
195 }
196
197 "!=" {
198 return NOT_EQUAL;
199 }
200
201 "&&" {
202 return AND;
203 }
204
205 "||" {
206 return OR;
207 }
208
209 "##" {
210 return PASTE;
211 }
212
213 "defined" {
214 return DEFINED;
215 }
216
217 {IDENTIFIER} {
218 yylval->str = xtalloc_strdup (yyextra, yytext);
219 return IDENTIFIER;
220 }
221
222 {PUNCTUATION} {
223 return yytext[0];
224 }
225
226 {OTHER}+ {
227 yylval->str = xtalloc_strdup (yyextra, yytext);
228 return OTHER;
229 }
230
231 {HSPACE}+ {
232 if (yyextra->space_tokens) {
233 return SPACE;
234 }
235 }
236
237 \n {
238 yyextra->lexing_if = 0;
239 yylineno++;
240 yycolumn = 0;
241 return NEWLINE;
242 }
243
244 /* Handle missing newline at EOF. */
245 <INITIAL><<EOF>> {
246 BEGIN DONE; /* Don't keep matching this rule forever. */
247 yyextra->lexing_if = 0;
248 return NEWLINE;
249 }
250
251 %%
252
253 void
254 glcpp_lex_set_source_string(glcpp_parser_t *parser, const char *shader)
255 {
256 yy_scan_string(shader, parser->scanner);
257 }