blob: 1cd95b238d2f0de8d05b3c363f294d3656a2e5b3 [file] [log] [blame]
Carl Worth3a37b872010-05-10 11:44:09 -07001%{
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>
Kenneth Graunke7e908a62010-07-02 15:31:26 -070027#include <ctype.h>
Carl Worth3a37b872010-05-10 11:44:09 -070028
Carl Wortha1e32bc2010-05-10 13:17:25 -070029#include "glcpp.h"
Carl Worth3a37b872010-05-10 11:44:09 -070030#include "glcpp-parse.h"
Kenneth Graunkedb938102010-06-16 17:41:12 -070031
Carl Wortha9bb4bc2010-07-20 15:03:20 -070032/* Flex annoyingly generates some functions without making them
33 * static. Let's declare them here. */
34int glcpp_get_column (yyscan_t yyscanner);
35void glcpp_set_column (int column_no , yyscan_t yyscanner);
36
Carl Worthfb905602010-07-20 15:53:14 -070037#define YY_NO_INPUT
38
Kenneth Graunkedb938102010-06-16 17:41:12 -070039#define YY_USER_ACTION \
40 do { \
41 yylloc->source = 0; \
42 yylloc->first_column = yycolumn + 1; \
Kenneth Graunke8f322212010-06-18 15:23:50 -070043 yylloc->first_line = yylineno; \
Kenneth Graunkedb938102010-06-16 17:41:12 -070044 yycolumn += yyleng; \
45 } while(0);
Carl Worthbc64b892010-08-11 13:09:14 -070046#define YY_USER_INIT yylineno = 1; yycolumn = 1;
Carl Worth3a37b872010-05-10 11:44:09 -070047%}
48
Kenneth Graunke465e03e2010-06-16 16:35:57 -070049%option bison-bridge bison-locations reentrant noyywrap
Carl Worth5070a202010-05-12 12:45:33 -070050%option extra-type="glcpp_parser_t *"
Kenneth Graunke254a4852010-06-16 11:51:43 -070051%option prefix="glcpp_"
Kenneth Graunkedb938102010-06-16 17:41:12 -070052%option stack
Ian Romanickab18be72010-08-13 13:08:54 -070053%option never-interactive
Carl Worth3a37b872010-05-10 11:44:09 -070054
Carl Worthfb905602010-07-20 15:53:14 -070055%x DONE COMMENT UNREACHABLE
Kenneth Graunkef82d6732010-06-16 12:53:19 -070056
Carl Worth0b27b5f2010-05-10 16:16:06 -070057SPACE [[:space:]]
58NONSPACE [^[:space:]]
Carl Worth33cc4002010-05-12 12:17:10 -070059NEWLINE [\n]
Carl Worth0b27b5f2010-05-10 16:16:06 -070060HSPACE [ \t]
Carl Worthe36a4d52010-05-14 17:29:24 -070061HASH ^{HSPACE}*#{HSPACE}*
Carl Worth0b27b5f2010-05-10 16:16:06 -070062IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]*
Carl Worth63101692010-05-29 05:07:24 -070063PUNCTUATION [][(){}.&*~!/%<>^|;,=+-]
Carl Worth3ff81672010-05-25 13:09:03 -070064OTHER [^][(){}.&*~!/%<>^|;,=#[:space:]+-]+
Carl Worth33cc4002010-05-12 12:17:10 -070065
Carl Worth03f6d5d2010-05-24 11:29:02 -070066DECIMAL_INTEGER [1-9][0-9]*[uU]?
67OCTAL_INTEGER 0[0-7]*[uU]?
68HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]?
69
Carl Worth3a37b872010-05-10 11:44:09 -070070%%
71
Carl Worth25714152010-06-01 12:18:43 -070072 /* Single-line comments */
Kenneth Graunkee6ae7af2010-06-21 15:11:01 -070073"//"[^\n]*\n {
Kenneth Graunkedb938102010-06-16 17:41:12 -070074 yylineno++;
75 yycolumn = 0;
Carl Worth25714152010-06-01 12:18:43 -070076 return NEWLINE;
77}
78
79 /* Multi-line comments */
Kenneth Graunkedb938102010-06-16 17:41:12 -070080"/*" { yy_push_state(COMMENT, yyscanner); }
81<COMMENT>[^*\n]*
82<COMMENT>[^*\n]*\n { yylineno++; yycolumn = 0; }
83<COMMENT>"*"+[^*/\n]*
84<COMMENT>"*"+[^*/\n]*\n { yylineno++; yycolumn = 0; }
85<COMMENT>"*"+"/" {
86 yy_pop_state(yyscanner);
Carl Worth25714152010-06-01 12:18:43 -070087 if (yyextra->space_tokens)
88 return SPACE;
89}
90
Eric Anholtd4a04f32010-07-28 16:58:39 -070091{HASH}(version) {
Kenneth Graunke1ffc1cd2010-08-03 20:21:52 -070092 yylval->str = talloc_strdup (yyextra, yytext);
Eric Anholtd4a04f32010-07-28 16:58:39 -070093 yylineno++;
94 yycolumn = 0;
95 yyextra->space_tokens = 0;
96 return HASH_VERSION;
97}
98
Kenneth Graunke3b73ea32010-06-16 12:21:17 -070099 /* glcpp doesn't handle #extension, #version, or #pragma directives.
100 * Simply pass them through to the main compiler's lexer/parser. */
Eric Anholtd4a04f32010-07-28 16:58:39 -0700101{HASH}(extension|pragma)[^\n]+ {
Kenneth Graunke1ffc1cd2010-08-03 20:21:52 -0700102 yylval->str = talloc_strdup (yyextra, yytext);
Kenneth Graunke8f322212010-06-18 15:23:50 -0700103 yylineno++;
104 yycolumn = 0;
Kenneth Graunke3b73ea32010-06-16 12:21:17 -0700105 return OTHER;
106}
107
Kenneth Graunke77260fc2010-06-17 14:36:34 -0700108{HASH}ifdef/.*\n {
Carl Worth1d7e03e2010-07-20 14:13:32 -0700109 yyextra->lexing_if = 1;
Kenneth Graunke77260fc2010-06-17 14:36:34 -0700110 yyextra->space_tokens = 0;
111 return HASH_IFDEF;
112}
113
114{HASH}ifndef/.*\n {
Carl Worth1d7e03e2010-07-20 14:13:32 -0700115 yyextra->lexing_if = 1;
Kenneth Graunke77260fc2010-06-17 14:36:34 -0700116 yyextra->space_tokens = 0;
117 return HASH_IFNDEF;
118}
119
Carl Worth1d7e03e2010-07-20 14:13:32 -0700120{HASH}if/[^_a-zA-Z0-9].*\n {
Carl Wortha771a402010-06-01 11:20:18 -0700121 yyextra->lexing_if = 1;
122 yyextra->space_tokens = 0;
123 return HASH_IF;
124}
125
126{HASH}elif/.*\n {
127 yyextra->lexing_if = 1;
128 yyextra->space_tokens = 0;
129 return HASH_ELIF;
130}
131
132{HASH}else/.*\n {
133 yyextra->space_tokens = 0;
134 return HASH_ELSE;
135}
136
137{HASH}endif/.*\n {
138 yyextra->space_tokens = 0;
139 return HASH_ENDIF;
140}
141
142 /* When skipping (due to an #if 0 or similar) consume anything
Carl Worth1d7e03e2010-07-20 14:13:32 -0700143 * up to a newline. We do this with less priority than any
Carl Wortha771a402010-06-01 11:20:18 -0700144 * #if-related directive (#if, #elif, #else, #endif), but with
145 * more priority than any other directive or token to avoid
146 * any side-effects from skipped content.
147 *
148 * We use the lexing_if flag to avoid skipping any part of an
149 * if conditional expression. */
150[^\n]+/\n {
Kenneth Graunke8f322212010-06-18 15:23:50 -0700151 /* Since this rule always matches, YY_USER_ACTION gets called for it,
152 * wrongly incrementing yycolumn. We undo that effect here. */
153 yycolumn -= yyleng;
Carl Wortha771a402010-06-01 11:20:18 -0700154 if (yyextra->lexing_if ||
155 yyextra->skip_stack == NULL ||
156 yyextra->skip_stack->type == SKIP_NO_SKIP)
157 {
158 REJECT;
159 }
160}
161
Kenneth Graunke7e908a62010-07-02 15:31:26 -0700162{HASH}error.* {
163 char *p;
164 for (p = yytext; !isalpha(p[0]); p++); /* skip " # " */
165 p += 5; /* skip "error" */
166 glcpp_error(yylloc, yyextra, "#error%s", p);
167}
168
Carl Worth3ff81672010-05-25 13:09:03 -0700169{HASH}define{HSPACE}+/{IDENTIFIER}"(" {
Carl Worthf34a0002010-05-25 16:59:02 -0700170 yyextra->space_tokens = 0;
Carl Worth3ff81672010-05-25 13:09:03 -0700171 return HASH_DEFINE_FUNC;
Carl Worthb20d33c2010-05-20 22:27:07 -0700172}
173
Carl Worth3ff81672010-05-25 13:09:03 -0700174{HASH}define {
Carl Worthf34a0002010-05-25 16:59:02 -0700175 yyextra->space_tokens = 0;
Carl Worth3ff81672010-05-25 13:09:03 -0700176 return HASH_DEFINE_OBJ;
Carl Worthb20d33c2010-05-20 22:27:07 -0700177}
178
Carl Worth3ff81672010-05-25 13:09:03 -0700179{HASH}undef {
Carl Worthf34a0002010-05-25 16:59:02 -0700180 yyextra->space_tokens = 0;
Carl Worth3ff81672010-05-25 13:09:03 -0700181 return HASH_UNDEF;
Carl Worth03f6d5d2010-05-24 11:29:02 -0700182}
183
Carl Worth3ff81672010-05-25 13:09:03 -0700184{HASH} {
Carl Worthf34a0002010-05-25 16:59:02 -0700185 yyextra->space_tokens = 0;
Carl Worth3ff81672010-05-25 13:09:03 -0700186 return HASH;
Carl Worth81f01432010-05-14 17:08:45 -0700187}
188
Carl Worth8fed1cd2010-05-26 09:32:12 -0700189{DECIMAL_INTEGER} {
Kenneth Graunke1ffc1cd2010-08-03 20:21:52 -0700190 yylval->str = talloc_strdup (yyextra, yytext);
Carl Worth050e3de2010-05-27 14:36:29 -0700191 return INTEGER_STRING;
Carl Worth8fed1cd2010-05-26 09:32:12 -0700192}
193
194{OCTAL_INTEGER} {
Kenneth Graunke1ffc1cd2010-08-03 20:21:52 -0700195 yylval->str = talloc_strdup (yyextra, yytext);
Carl Worth050e3de2010-05-27 14:36:29 -0700196 return INTEGER_STRING;
Carl Worth8fed1cd2010-05-26 09:32:12 -0700197}
198
199{HEXADECIMAL_INTEGER} {
Kenneth Graunke1ffc1cd2010-08-03 20:21:52 -0700200 yylval->str = talloc_strdup (yyextra, yytext);
Carl Worth050e3de2010-05-27 14:36:29 -0700201 return INTEGER_STRING;
Carl Worth8fed1cd2010-05-26 09:32:12 -0700202}
203
Carl Worthf34a0002010-05-25 16:59:02 -0700204"<<" {
205 return LEFT_SHIFT;
Carl Worthb1854fd2010-05-25 16:28:26 -0700206}
207
Carl Worthf34a0002010-05-25 16:59:02 -0700208">>" {
209 return RIGHT_SHIFT;
Carl Worthb1854fd2010-05-25 16:28:26 -0700210}
211
Carl Worthf34a0002010-05-25 16:59:02 -0700212"<=" {
213 return LESS_OR_EQUAL;
214}
215
216">=" {
217 return GREATER_OR_EQUAL;
218}
219
220"==" {
221 return EQUAL;
222}
223
224"!=" {
225 return NOT_EQUAL;
226}
227
228"&&" {
229 return AND;
230}
231
232"||" {
233 return OR;
234}
235
236"##" {
237 return PASTE;
238}
239
Carl Worth8fed1cd2010-05-26 09:32:12 -0700240"defined" {
241 return DEFINED;
242}
243
Carl Worth16c1e982010-05-26 09:35:34 -0700244{IDENTIFIER} {
Kenneth Graunke1ffc1cd2010-08-03 20:21:52 -0700245 yylval->str = talloc_strdup (yyextra, yytext);
Carl Worth16c1e982010-05-26 09:35:34 -0700246 return IDENTIFIER;
247}
248
Carl Worthf34a0002010-05-25 16:59:02 -0700249{PUNCTUATION} {
250 return yytext[0];
Carl Worthb1854fd2010-05-25 16:28:26 -0700251}
252
Carl Worth9fb8b7a2010-05-25 15:04:32 -0700253{OTHER}+ {
Kenneth Graunke1ffc1cd2010-08-03 20:21:52 -0700254 yylval->str = talloc_strdup (yyextra, yytext);
Carl Worth9fb8b7a2010-05-25 15:04:32 -0700255 return OTHER;
Carl Worth3ff81672010-05-25 13:09:03 -0700256}
257
Carl Worth9fb8b7a2010-05-25 15:04:32 -0700258{HSPACE}+ {
Carl Worthf34a0002010-05-25 16:59:02 -0700259 if (yyextra->space_tokens) {
Carl Worthf34a0002010-05-25 16:59:02 -0700260 return SPACE;
261 }
Carl Worth0a93cbb2010-05-13 10:29:07 -0700262}
Carl Worthfcbbb462010-05-13 09:36:23 -0700263
Carl Worth3ff81672010-05-25 13:09:03 -0700264\n {
Carl Wortha771a402010-06-01 11:20:18 -0700265 yyextra->lexing_if = 0;
Kenneth Graunkedb938102010-06-16 17:41:12 -0700266 yylineno++;
267 yycolumn = 0;
Carl Worth3ff81672010-05-25 13:09:03 -0700268 return NEWLINE;
Carl Worth33cc4002010-05-12 12:17:10 -0700269}
Carl Worth3a37b872010-05-10 11:44:09 -0700270
Kenneth Graunkef82d6732010-06-16 12:53:19 -0700271 /* Handle missing newline at EOF. */
272<INITIAL><<EOF>> {
273 BEGIN DONE; /* Don't keep matching this rule forever. */
274 yyextra->lexing_if = 0;
275 return NEWLINE;
276}
277
Carl Worthfb905602010-07-20 15:53:14 -0700278 /* We don't actually use the UNREACHABLE start condition. We
279 only have this action here so that we can pretend to call some
280 generated functions, (to avoid "defined but not used"
281 warnings. */
282<UNREACHABLE>. {
283 unput('.');
284 yy_top_state(yyextra);
285}
286
Carl Worth3a37b872010-05-10 11:44:09 -0700287%%
Kenneth Graunke1b1f43e2010-06-16 12:01:17 -0700288
289void
290glcpp_lex_set_source_string(glcpp_parser_t *parser, const char *shader)
291{
292 yy_scan_string(shader, parser->scanner);
293}