blob: a4c891bdc69297fa649e2703f422d2ea2aa6b994 [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);
Kenneth Graunke388ab9f2010-07-07 11:40:51 -070046#define YY_USER_INIT yylineno = 0; yycolumn = 0;
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
Carl Worth3a37b872010-05-10 11:44:09 -070053
Carl Worthfb905602010-07-20 15:53:14 -070054%x DONE COMMENT UNREACHABLE
Kenneth Graunkef82d6732010-06-16 12:53:19 -070055
Carl Worth0b27b5f2010-05-10 16:16:06 -070056SPACE [[:space:]]
57NONSPACE [^[:space:]]
Carl Worth33cc4002010-05-12 12:17:10 -070058NEWLINE [\n]
Carl Worth0b27b5f2010-05-10 16:16:06 -070059HSPACE [ \t]
Carl Worthe36a4d52010-05-14 17:29:24 -070060HASH ^{HSPACE}*#{HSPACE}*
Carl Worth0b27b5f2010-05-10 16:16:06 -070061IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]*
Carl Worth63101692010-05-29 05:07:24 -070062PUNCTUATION [][(){}.&*~!/%<>^|;,=+-]
Carl Worth3ff81672010-05-25 13:09:03 -070063OTHER [^][(){}.&*~!/%<>^|;,=#[:space:]+-]+
Carl Worth33cc4002010-05-12 12:17:10 -070064
Carl Worth03f6d5d2010-05-24 11:29:02 -070065DECIMAL_INTEGER [1-9][0-9]*[uU]?
66OCTAL_INTEGER 0[0-7]*[uU]?
67HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]?
68
Carl Worth3a37b872010-05-10 11:44:09 -070069%%
70
Carl Worth25714152010-06-01 12:18:43 -070071 /* Single-line comments */
Kenneth Graunkee6ae7af2010-06-21 15:11:01 -070072"//"[^\n]*\n {
Kenneth Graunkedb938102010-06-16 17:41:12 -070073 yylineno++;
74 yycolumn = 0;
Carl Worth25714152010-06-01 12:18:43 -070075 return NEWLINE;
76}
77
78 /* Multi-line comments */
Kenneth Graunkedb938102010-06-16 17:41:12 -070079"/*" { yy_push_state(COMMENT, yyscanner); }
80<COMMENT>[^*\n]*
81<COMMENT>[^*\n]*\n { yylineno++; yycolumn = 0; }
82<COMMENT>"*"+[^*/\n]*
83<COMMENT>"*"+[^*/\n]*\n { yylineno++; yycolumn = 0; }
84<COMMENT>"*"+"/" {
85 yy_pop_state(yyscanner);
Carl Worth25714152010-06-01 12:18:43 -070086 if (yyextra->space_tokens)
87 return SPACE;
88}
89
Kenneth Graunke3b73ea32010-06-16 12:21:17 -070090 /* glcpp doesn't handle #extension, #version, or #pragma directives.
91 * Simply pass them through to the main compiler's lexer/parser. */
Kenneth Graunke03ee3382010-06-18 15:41:00 -070092{HASH}(extension|version|pragma)[^\n]+ {
Kenneth Graunkee0e429f2010-06-16 16:26:28 -070093 yylval->str = xtalloc_strdup (yyextra, yytext);
Kenneth Graunke8f322212010-06-18 15:23:50 -070094 yylineno++;
95 yycolumn = 0;
Kenneth Graunke3b73ea32010-06-16 12:21:17 -070096 return OTHER;
97}
98
Kenneth Graunke77260fc2010-06-17 14:36:34 -070099{HASH}ifdef/.*\n {
Carl Worth1d7e03e2010-07-20 14:13:32 -0700100 yyextra->lexing_if = 1;
Kenneth Graunke77260fc2010-06-17 14:36:34 -0700101 yyextra->space_tokens = 0;
102 return HASH_IFDEF;
103}
104
105{HASH}ifndef/.*\n {
Carl Worth1d7e03e2010-07-20 14:13:32 -0700106 yyextra->lexing_if = 1;
Kenneth Graunke77260fc2010-06-17 14:36:34 -0700107 yyextra->space_tokens = 0;
108 return HASH_IFNDEF;
109}
110
Carl Worth1d7e03e2010-07-20 14:13:32 -0700111{HASH}if/[^_a-zA-Z0-9].*\n {
Carl Wortha771a402010-06-01 11:20:18 -0700112 yyextra->lexing_if = 1;
113 yyextra->space_tokens = 0;
114 return HASH_IF;
115}
116
117{HASH}elif/.*\n {
118 yyextra->lexing_if = 1;
119 yyextra->space_tokens = 0;
120 return HASH_ELIF;
121}
122
123{HASH}else/.*\n {
124 yyextra->space_tokens = 0;
125 return HASH_ELSE;
126}
127
128{HASH}endif/.*\n {
129 yyextra->space_tokens = 0;
130 return HASH_ENDIF;
131}
132
133 /* When skipping (due to an #if 0 or similar) consume anything
Carl Worth1d7e03e2010-07-20 14:13:32 -0700134 * up to a newline. We do this with less priority than any
Carl Wortha771a402010-06-01 11:20:18 -0700135 * #if-related directive (#if, #elif, #else, #endif), but with
136 * more priority than any other directive or token to avoid
137 * any side-effects from skipped content.
138 *
139 * We use the lexing_if flag to avoid skipping any part of an
140 * if conditional expression. */
141[^\n]+/\n {
Kenneth Graunke8f322212010-06-18 15:23:50 -0700142 /* Since this rule always matches, YY_USER_ACTION gets called for it,
143 * wrongly incrementing yycolumn. We undo that effect here. */
144 yycolumn -= yyleng;
Carl Wortha771a402010-06-01 11:20:18 -0700145 if (yyextra->lexing_if ||
146 yyextra->skip_stack == NULL ||
147 yyextra->skip_stack->type == SKIP_NO_SKIP)
148 {
149 REJECT;
150 }
151}
152
Kenneth Graunke7e908a62010-07-02 15:31:26 -0700153{HASH}error.* {
154 char *p;
155 for (p = yytext; !isalpha(p[0]); p++); /* skip " # " */
156 p += 5; /* skip "error" */
157 glcpp_error(yylloc, yyextra, "#error%s", p);
158}
159
Carl Worth3ff81672010-05-25 13:09:03 -0700160{HASH}define{HSPACE}+/{IDENTIFIER}"(" {
Carl Worthf34a0002010-05-25 16:59:02 -0700161 yyextra->space_tokens = 0;
Carl Worth3ff81672010-05-25 13:09:03 -0700162 return HASH_DEFINE_FUNC;
Carl Worthb20d33c2010-05-20 22:27:07 -0700163}
164
Carl Worth3ff81672010-05-25 13:09:03 -0700165{HASH}define {
Carl Worthf34a0002010-05-25 16:59:02 -0700166 yyextra->space_tokens = 0;
Carl Worth3ff81672010-05-25 13:09:03 -0700167 return HASH_DEFINE_OBJ;
Carl Worthb20d33c2010-05-20 22:27:07 -0700168}
169
Carl Worth3ff81672010-05-25 13:09:03 -0700170{HASH}undef {
Carl Worthf34a0002010-05-25 16:59:02 -0700171 yyextra->space_tokens = 0;
Carl Worth3ff81672010-05-25 13:09:03 -0700172 return HASH_UNDEF;
Carl Worth03f6d5d2010-05-24 11:29:02 -0700173}
174
Carl Worth3ff81672010-05-25 13:09:03 -0700175{HASH} {
Carl Worthf34a0002010-05-25 16:59:02 -0700176 yyextra->space_tokens = 0;
Carl Worth3ff81672010-05-25 13:09:03 -0700177 return HASH;
Carl Worth81f01432010-05-14 17:08:45 -0700178}
179
Carl Worth8fed1cd2010-05-26 09:32:12 -0700180{DECIMAL_INTEGER} {
Kenneth Graunkee0e429f2010-06-16 16:26:28 -0700181 yylval->str = xtalloc_strdup (yyextra, yytext);
Carl Worth050e3de2010-05-27 14:36:29 -0700182 return INTEGER_STRING;
Carl Worth8fed1cd2010-05-26 09:32:12 -0700183}
184
185{OCTAL_INTEGER} {
Kenneth Graunkee0e429f2010-06-16 16:26:28 -0700186 yylval->str = xtalloc_strdup (yyextra, yytext);
Carl Worth050e3de2010-05-27 14:36:29 -0700187 return INTEGER_STRING;
Carl Worth8fed1cd2010-05-26 09:32:12 -0700188}
189
190{HEXADECIMAL_INTEGER} {
Kenneth Graunkee0e429f2010-06-16 16:26:28 -0700191 yylval->str = xtalloc_strdup (yyextra, yytext);
Carl Worth050e3de2010-05-27 14:36:29 -0700192 return INTEGER_STRING;
Carl Worth8fed1cd2010-05-26 09:32:12 -0700193}
194
Carl Worthf34a0002010-05-25 16:59:02 -0700195"<<" {
196 return LEFT_SHIFT;
Carl Worthb1854fd2010-05-25 16:28:26 -0700197}
198
Carl Worthf34a0002010-05-25 16:59:02 -0700199">>" {
200 return RIGHT_SHIFT;
Carl Worthb1854fd2010-05-25 16:28:26 -0700201}
202
Carl Worthf34a0002010-05-25 16:59:02 -0700203"<=" {
204 return LESS_OR_EQUAL;
205}
206
207">=" {
208 return GREATER_OR_EQUAL;
209}
210
211"==" {
212 return EQUAL;
213}
214
215"!=" {
216 return NOT_EQUAL;
217}
218
219"&&" {
220 return AND;
221}
222
223"||" {
224 return OR;
225}
226
227"##" {
228 return PASTE;
229}
230
Carl Worth8fed1cd2010-05-26 09:32:12 -0700231"defined" {
232 return DEFINED;
233}
234
Carl Worth16c1e982010-05-26 09:35:34 -0700235{IDENTIFIER} {
Kenneth Graunkee0e429f2010-06-16 16:26:28 -0700236 yylval->str = xtalloc_strdup (yyextra, yytext);
Carl Worth16c1e982010-05-26 09:35:34 -0700237 return IDENTIFIER;
238}
239
Carl Worthf34a0002010-05-25 16:59:02 -0700240{PUNCTUATION} {
241 return yytext[0];
Carl Worthb1854fd2010-05-25 16:28:26 -0700242}
243
Carl Worth9fb8b7a2010-05-25 15:04:32 -0700244{OTHER}+ {
Kenneth Graunkee0e429f2010-06-16 16:26:28 -0700245 yylval->str = xtalloc_strdup (yyextra, yytext);
Carl Worth9fb8b7a2010-05-25 15:04:32 -0700246 return OTHER;
Carl Worth3ff81672010-05-25 13:09:03 -0700247}
248
Carl Worth9fb8b7a2010-05-25 15:04:32 -0700249{HSPACE}+ {
Carl Worthf34a0002010-05-25 16:59:02 -0700250 if (yyextra->space_tokens) {
Carl Worthf34a0002010-05-25 16:59:02 -0700251 return SPACE;
252 }
Carl Worth0a93cbb2010-05-13 10:29:07 -0700253}
Carl Worthfcbbb462010-05-13 09:36:23 -0700254
Carl Worth3ff81672010-05-25 13:09:03 -0700255\n {
Carl Wortha771a402010-06-01 11:20:18 -0700256 yyextra->lexing_if = 0;
Kenneth Graunkedb938102010-06-16 17:41:12 -0700257 yylineno++;
258 yycolumn = 0;
Carl Worth3ff81672010-05-25 13:09:03 -0700259 return NEWLINE;
Carl Worth33cc4002010-05-12 12:17:10 -0700260}
Carl Worth3a37b872010-05-10 11:44:09 -0700261
Kenneth Graunkef82d6732010-06-16 12:53:19 -0700262 /* Handle missing newline at EOF. */
263<INITIAL><<EOF>> {
264 BEGIN DONE; /* Don't keep matching this rule forever. */
265 yyextra->lexing_if = 0;
266 return NEWLINE;
267}
268
Carl Worthfb905602010-07-20 15:53:14 -0700269 /* We don't actually use the UNREACHABLE start condition. We
270 only have this action here so that we can pretend to call some
271 generated functions, (to avoid "defined but not used"
272 warnings. */
273<UNREACHABLE>. {
274 unput('.');
275 yy_top_state(yyextra);
276}
277
Carl Worth3a37b872010-05-10 11:44:09 -0700278%%
Kenneth Graunke1b1f43e2010-06-16 12:01:17 -0700279
280void
281glcpp_lex_set_source_string(glcpp_parser_t *parser, const char *shader)
282{
283 yy_scan_string(shader, parser->scanner);
284}