2010-05-10 11:44:09 -07:00
|
|
|
%{
|
|
|
|
|
/*
|
|
|
|
|
* Copyright © 2010 Intel Corporation
|
|
|
|
|
*
|
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
|
|
|
* to deal in the Software without restriction, including without limitation
|
|
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
|
|
|
*
|
|
|
|
|
* The above copyright notice and this permission notice (including the next
|
|
|
|
|
* paragraph) shall be included in all copies or substantial portions of the
|
|
|
|
|
* Software.
|
|
|
|
|
*
|
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
|
* DEALINGS IN THE SOFTWARE.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
2010-07-02 15:31:26 -07:00
|
|
|
#include <ctype.h>
|
2010-05-10 11:44:09 -07:00
|
|
|
|
2010-05-10 13:17:25 -07:00
|
|
|
#include "glcpp.h"
|
2010-05-10 11:44:09 -07:00
|
|
|
#include "glcpp-parse.h"
|
2010-06-16 17:41:12 -07:00
|
|
|
|
2010-07-20 15:03:20 -07:00
|
|
|
/* Flex annoyingly generates some functions without making them
|
|
|
|
|
* static. Let's declare them here. */
|
|
|
|
|
int glcpp_get_column (yyscan_t yyscanner);
|
|
|
|
|
void glcpp_set_column (int column_no , yyscan_t yyscanner);
|
|
|
|
|
|
2011-03-04 12:49:55 +00:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
|
#define YY_NO_UNISTD_H
|
|
|
|
|
#endif
|
|
|
|
|
|
2010-07-20 15:53:14 -07:00
|
|
|
#define YY_NO_INPUT
|
|
|
|
|
|
2010-06-16 17:41:12 -07:00
|
|
|
#define YY_USER_ACTION \
|
|
|
|
|
do { \
|
|
|
|
|
yylloc->first_column = yycolumn + 1; \
|
2010-06-18 15:23:50 -07:00
|
|
|
yylloc->first_line = yylineno; \
|
2010-06-16 17:41:12 -07:00
|
|
|
yycolumn += yyleng; \
|
|
|
|
|
} while(0);
|
2010-08-23 09:29:49 -07:00
|
|
|
|
|
|
|
|
#define YY_USER_INIT \
|
|
|
|
|
do { \
|
|
|
|
|
yylineno = 1; \
|
|
|
|
|
yycolumn = 1; \
|
|
|
|
|
yylloc->source = 0; \
|
|
|
|
|
} while(0)
|
2010-05-10 11:44:09 -07:00
|
|
|
%}
|
|
|
|
|
|
2010-06-16 16:35:57 -07:00
|
|
|
%option bison-bridge bison-locations reentrant noyywrap
|
2010-05-12 12:45:33 -07:00
|
|
|
%option extra-type="glcpp_parser_t *"
|
2010-06-16 11:51:43 -07:00
|
|
|
%option prefix="glcpp_"
|
2010-06-16 17:41:12 -07:00
|
|
|
%option stack
|
2010-08-13 13:08:54 -07:00
|
|
|
%option never-interactive
|
2010-05-10 11:44:09 -07:00
|
|
|
|
2011-03-01 12:24:58 -08:00
|
|
|
%x DONE COMMENT UNREACHABLE SKIP
|
2010-06-16 12:53:19 -07:00
|
|
|
|
2010-05-10 16:16:06 -07:00
|
|
|
SPACE [[:space:]]
|
|
|
|
|
NONSPACE [^[:space:]]
|
2010-05-12 12:17:10 -07:00
|
|
|
NEWLINE [\n]
|
2010-05-10 16:16:06 -07:00
|
|
|
HSPACE [ \t]
|
2010-05-14 17:29:24 -07:00
|
|
|
HASH ^{HSPACE}*#{HSPACE}*
|
2010-05-10 16:16:06 -07:00
|
|
|
IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]*
|
2010-05-29 05:07:24 -07:00
|
|
|
PUNCTUATION [][(){}.&*~!/%<>^|;,=+-]
|
2010-05-25 13:09:03 -07:00
|
|
|
OTHER [^][(){}.&*~!/%<>^|;,=#[:space:]+-]+
|
2010-05-12 12:17:10 -07:00
|
|
|
|
2010-08-23 09:31:42 -07:00
|
|
|
DIGITS [0-9][0-9]*
|
2010-05-24 11:29:02 -07:00
|
|
|
DECIMAL_INTEGER [1-9][0-9]*[uU]?
|
|
|
|
|
OCTAL_INTEGER 0[0-7]*[uU]?
|
|
|
|
|
HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]?
|
|
|
|
|
|
2010-05-10 11:44:09 -07:00
|
|
|
%%
|
2011-03-01 12:24:58 -08:00
|
|
|
/* Implicitly switch between SKIP and INITIAL (non-skipping);
|
|
|
|
|
* don't switch if some other state was explicitly set.
|
|
|
|
|
*/
|
|
|
|
|
glcpp_parser_t *parser = yyextra;
|
|
|
|
|
if (YY_START == 0 || YY_START == SKIP) {
|
|
|
|
|
if (parser->lexing_if || parser->skip_stack == NULL || parser->skip_stack->type == SKIP_NO_SKIP) {
|
|
|
|
|
BEGIN 0;
|
|
|
|
|
} else {
|
|
|
|
|
BEGIN SKIP;
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-05-10 11:44:09 -07:00
|
|
|
|
2010-06-01 12:18:43 -07:00
|
|
|
/* Single-line comments */
|
2010-08-17 22:17:09 -07:00
|
|
|
"//"[^\n]* {
|
2010-06-01 12:18:43 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Multi-line comments */
|
2010-06-16 17:41:12 -07:00
|
|
|
"/*" { yy_push_state(COMMENT, yyscanner); }
|
|
|
|
|
<COMMENT>[^*\n]*
|
2010-10-20 21:51:03 -07:00
|
|
|
<COMMENT>[^*\n]*\n { yylineno++; yycolumn = 0; return NEWLINE; }
|
2010-06-16 17:41:12 -07:00
|
|
|
<COMMENT>"*"+[^*/\n]*
|
2010-10-20 21:51:03 -07:00
|
|
|
<COMMENT>"*"+[^*/\n]*\n { yylineno++; yycolumn = 0; return NEWLINE; }
|
2010-06-16 17:41:12 -07:00
|
|
|
<COMMENT>"*"+"/" {
|
|
|
|
|
yy_pop_state(yyscanner);
|
2010-06-01 12:18:43 -07:00
|
|
|
if (yyextra->space_tokens)
|
|
|
|
|
return SPACE;
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-16 13:42:04 -07:00
|
|
|
{HASH}version {
|
2011-01-21 14:32:31 -08:00
|
|
|
yylval->str = ralloc_strdup (yyextra, yytext);
|
2010-07-28 16:58:39 -07:00
|
|
|
yyextra->space_tokens = 0;
|
|
|
|
|
return HASH_VERSION;
|
|
|
|
|
}
|
|
|
|
|
|
2010-06-16 12:21:17 -07:00
|
|
|
/* glcpp doesn't handle #extension, #version, or #pragma directives.
|
|
|
|
|
* Simply pass them through to the main compiler's lexer/parser. */
|
2010-07-28 16:58:39 -07:00
|
|
|
{HASH}(extension|pragma)[^\n]+ {
|
2011-01-21 14:32:31 -08:00
|
|
|
yylval->str = ralloc_strdup (yyextra, yytext);
|
2010-06-18 15:23:50 -07:00
|
|
|
yylineno++;
|
|
|
|
|
yycolumn = 0;
|
2010-06-16 12:21:17 -07:00
|
|
|
return OTHER;
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-23 09:31:42 -07:00
|
|
|
{HASH}line{HSPACE}+{DIGITS}{HSPACE}+{DIGITS}{HSPACE}*$ {
|
2010-08-18 17:38:05 -07:00
|
|
|
/* Eat characters until the first digit is
|
|
|
|
|
* encountered
|
|
|
|
|
*/
|
|
|
|
|
char *ptr = yytext;
|
|
|
|
|
while (!isdigit(*ptr))
|
|
|
|
|
ptr++;
|
|
|
|
|
|
|
|
|
|
/* Subtract one from the line number because
|
|
|
|
|
* yylineno is zero-based instead of
|
|
|
|
|
* one-based.
|
|
|
|
|
*/
|
|
|
|
|
yylineno = strtol(ptr, &ptr, 0) - 1;
|
|
|
|
|
yylloc->source = strtol(ptr, NULL, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-23 09:31:42 -07:00
|
|
|
{HASH}line{HSPACE}+{DIGITS}{HSPACE}*$ {
|
2010-08-18 17:38:05 -07:00
|
|
|
/* Eat characters until the first digit is
|
|
|
|
|
* encountered
|
|
|
|
|
*/
|
|
|
|
|
char *ptr = yytext;
|
|
|
|
|
while (!isdigit(*ptr))
|
|
|
|
|
ptr++;
|
|
|
|
|
|
|
|
|
|
/* Subtract one from the line number because
|
|
|
|
|
* yylineno is zero-based instead of
|
|
|
|
|
* one-based.
|
|
|
|
|
*/
|
|
|
|
|
yylineno = strtol(ptr, &ptr, 0) - 1;
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-01 12:24:58 -08:00
|
|
|
<SKIP,INITIAL>{
|
2011-03-03 09:52:36 -08:00
|
|
|
{HASH}ifdef {
|
2010-07-20 14:13:32 -07:00
|
|
|
yyextra->lexing_if = 1;
|
2010-06-17 14:36:34 -07:00
|
|
|
yyextra->space_tokens = 0;
|
|
|
|
|
return HASH_IFDEF;
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-03 09:52:36 -08:00
|
|
|
{HASH}ifndef {
|
2010-07-20 14:13:32 -07:00
|
|
|
yyextra->lexing_if = 1;
|
2010-06-17 14:36:34 -07:00
|
|
|
yyextra->space_tokens = 0;
|
|
|
|
|
return HASH_IFNDEF;
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-03 09:52:36 -08:00
|
|
|
{HASH}if/[^_a-zA-Z0-9] {
|
2010-06-01 11:20:18 -07:00
|
|
|
yyextra->lexing_if = 1;
|
2010-05-25 16:59:02 -07:00
|
|
|
yyextra->space_tokens = 0;
|
2010-06-01 11:20:18 -07:00
|
|
|
return HASH_IF;
|
2010-05-20 22:27:07 -07:00
|
|
|
}
|
|
|
|
|
|
2011-03-03 09:52:36 -08:00
|
|
|
{HASH}elif {
|
2010-06-01 11:20:18 -07:00
|
|
|
yyextra->lexing_if = 1;
|
2010-05-25 16:59:02 -07:00
|
|
|
yyextra->space_tokens = 0;
|
2010-06-01 11:20:18 -07:00
|
|
|
return HASH_ELIF;
|
2010-05-24 11:29:02 -07:00
|
|
|
}
|
|
|
|
|
|
2011-03-03 09:52:36 -08:00
|
|
|
{HASH}else {
|
2010-05-25 16:59:02 -07:00
|
|
|
yyextra->space_tokens = 0;
|
2010-06-01 11:20:18 -07:00
|
|
|
return HASH_ELSE;
|
2010-05-24 11:29:02 -07:00
|
|
|
}
|
|
|
|
|
|
2011-03-03 09:52:36 -08:00
|
|
|
{HASH}endif {
|
2010-05-26 09:32:12 -07:00
|
|
|
yyextra->space_tokens = 0;
|
2010-06-01 11:20:18 -07:00
|
|
|
return HASH_ENDIF;
|
2010-05-26 09:32:12 -07:00
|
|
|
}
|
2010-06-01 11:20:18 -07:00
|
|
|
}
|
|
|
|
|
|
2011-03-01 12:24:58 -08:00
|
|
|
<SKIP>[^\n] ;
|
|
|
|
|
|
2010-07-02 15:31:26 -07:00
|
|
|
{HASH}error.* {
|
|
|
|
|
char *p;
|
|
|
|
|
for (p = yytext; !isalpha(p[0]); p++); /* skip " # " */
|
|
|
|
|
p += 5; /* skip "error" */
|
|
|
|
|
glcpp_error(yylloc, yyextra, "#error%s", p);
|
|
|
|
|
}
|
|
|
|
|
|
2010-06-01 11:20:18 -07:00
|
|
|
{HASH}define{HSPACE}+/{IDENTIFIER}"(" {
|
2010-05-26 09:32:12 -07:00
|
|
|
yyextra->space_tokens = 0;
|
2010-06-01 11:20:18 -07:00
|
|
|
return HASH_DEFINE_FUNC;
|
2010-05-26 09:32:12 -07:00
|
|
|
}
|
|
|
|
|
|
2010-06-01 11:20:18 -07:00
|
|
|
{HASH}define {
|
2010-05-26 09:32:12 -07:00
|
|
|
yyextra->space_tokens = 0;
|
2010-06-01 11:20:18 -07:00
|
|
|
return HASH_DEFINE_OBJ;
|
2010-05-26 09:32:12 -07:00
|
|
|
}
|
|
|
|
|
|
2010-06-01 11:20:18 -07:00
|
|
|
{HASH}undef {
|
2010-05-26 09:32:12 -07:00
|
|
|
yyextra->space_tokens = 0;
|
2010-06-01 11:20:18 -07:00
|
|
|
return HASH_UNDEF;
|
2010-05-26 09:32:12 -07:00
|
|
|
}
|
|
|
|
|
|
2010-05-25 13:09:03 -07:00
|
|
|
{HASH} {
|
2010-05-25 16:59:02 -07:00
|
|
|
yyextra->space_tokens = 0;
|
2010-05-25 13:09:03 -07:00
|
|
|
return HASH;
|
2010-05-20 22:27:07 -07:00
|
|
|
}
|
|
|
|
|
|
2010-05-26 09:32:12 -07:00
|
|
|
{DECIMAL_INTEGER} {
|
2011-01-21 14:32:31 -08:00
|
|
|
yylval->str = ralloc_strdup (yyextra, yytext);
|
2010-05-27 14:36:29 -07:00
|
|
|
return INTEGER_STRING;
|
2010-05-26 09:32:12 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{OCTAL_INTEGER} {
|
2011-01-21 14:32:31 -08:00
|
|
|
yylval->str = ralloc_strdup (yyextra, yytext);
|
2010-05-27 14:36:29 -07:00
|
|
|
return INTEGER_STRING;
|
2010-05-26 09:32:12 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{HEXADECIMAL_INTEGER} {
|
2011-01-21 14:32:31 -08:00
|
|
|
yylval->str = ralloc_strdup (yyextra, yytext);
|
2010-05-27 14:36:29 -07:00
|
|
|
return INTEGER_STRING;
|
2010-05-26 09:32:12 -07:00
|
|
|
}
|
|
|
|
|
|
2010-05-25 16:59:02 -07:00
|
|
|
"<<" {
|
2010-05-24 10:37:38 -07:00
|
|
|
return LEFT_SHIFT;
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-25 16:59:02 -07:00
|
|
|
">>" {
|
2010-05-24 10:37:38 -07:00
|
|
|
return RIGHT_SHIFT;
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-25 16:59:02 -07:00
|
|
|
"<=" {
|
2010-05-24 10:37:38 -07:00
|
|
|
return LESS_OR_EQUAL;
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-25 16:59:02 -07:00
|
|
|
">=" {
|
2010-05-24 10:37:38 -07:00
|
|
|
return GREATER_OR_EQUAL;
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-25 16:59:02 -07:00
|
|
|
"==" {
|
2010-05-24 10:37:38 -07:00
|
|
|
return EQUAL;
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-25 16:59:02 -07:00
|
|
|
"!=" {
|
2010-05-24 10:37:38 -07:00
|
|
|
return NOT_EQUAL;
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-25 16:59:02 -07:00
|
|
|
"&&" {
|
2010-05-24 10:37:38 -07:00
|
|
|
return AND;
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-25 16:59:02 -07:00
|
|
|
"||" {
|
2010-05-24 10:37:38 -07:00
|
|
|
return OR;
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-25 16:59:02 -07:00
|
|
|
"##" {
|
2010-05-25 13:09:03 -07:00
|
|
|
return PASTE;
|
2010-05-20 22:27:07 -07:00
|
|
|
}
|
|
|
|
|
|
2010-05-26 09:32:12 -07:00
|
|
|
"defined" {
|
|
|
|
|
return DEFINED;
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-26 09:35:34 -07:00
|
|
|
{IDENTIFIER} {
|
2011-01-21 14:32:31 -08:00
|
|
|
yylval->str = ralloc_strdup (yyextra, yytext);
|
2010-05-26 09:35:34 -07:00
|
|
|
return IDENTIFIER;
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-25 16:59:02 -07:00
|
|
|
{PUNCTUATION} {
|
2010-05-25 13:09:03 -07:00
|
|
|
return yytext[0];
|
2010-05-19 13:28:24 -07:00
|
|
|
}
|
|
|
|
|
|
2010-05-25 15:04:32 -07:00
|
|
|
{OTHER}+ {
|
2011-01-21 14:32:31 -08:00
|
|
|
yylval->str = ralloc_strdup (yyextra, yytext);
|
2010-05-25 15:04:32 -07:00
|
|
|
return OTHER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{HSPACE}+ {
|
2010-05-25 16:59:02 -07:00
|
|
|
if (yyextra->space_tokens) {
|
|
|
|
|
return SPACE;
|
|
|
|
|
}
|
2010-05-12 13:19:23 -07:00
|
|
|
}
|
|
|
|
|
|
2011-03-01 12:24:58 -08:00
|
|
|
<SKIP,INITIAL>\n {
|
2010-06-01 11:20:18 -07:00
|
|
|
yyextra->lexing_if = 0;
|
2010-06-16 17:41:12 -07:00
|
|
|
yylineno++;
|
|
|
|
|
yycolumn = 0;
|
2010-05-25 15:04:32 -07:00
|
|
|
return NEWLINE;
|
|
|
|
|
}
|
|
|
|
|
|
2010-06-16 12:53:19 -07:00
|
|
|
/* Handle missing newline at EOF. */
|
|
|
|
|
<INITIAL><<EOF>> {
|
|
|
|
|
BEGIN DONE; /* Don't keep matching this rule forever. */
|
|
|
|
|
yyextra->lexing_if = 0;
|
|
|
|
|
return NEWLINE;
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-20 15:53:14 -07:00
|
|
|
/* We don't actually use the UNREACHABLE start condition. We
|
|
|
|
|
only have this action here so that we can pretend to call some
|
|
|
|
|
generated functions, (to avoid "defined but not used"
|
|
|
|
|
warnings. */
|
|
|
|
|
<UNREACHABLE>. {
|
|
|
|
|
unput('.');
|
|
|
|
|
yy_top_state(yyextra);
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-10 11:44:09 -07:00
|
|
|
%%
|
2010-06-16 12:01:17 -07:00
|
|
|
|
|
|
|
|
void
|
|
|
|
|
glcpp_lex_set_source_string(glcpp_parser_t *parser, const char *shader)
|
|
|
|
|
{
|
|
|
|
|
yy_scan_string(shader, parser->scanner);
|
|
|
|
|
}
|