summaryrefslogtreecommitdiffstats
path: root/src/glsl/glcpp/glcpp-parse.y
diff options
context:
space:
mode:
Diffstat (limited to 'src/glsl/glcpp/glcpp-parse.y')
-rw-r--r--src/glsl/glcpp/glcpp-parse.y115
1 files changed, 64 insertions, 51 deletions
diff --git a/src/glsl/glcpp/glcpp-parse.y b/src/glsl/glcpp/glcpp-parse.y
index 7454fb0112f..2952bf84d8d 100644
--- a/src/glsl/glcpp/glcpp-parse.y
+++ b/src/glsl/glcpp/glcpp-parse.y
@@ -167,11 +167,11 @@ add_builtin_define(glcpp_parser_t *parser, const char *name, int value);
/* We use HASH_TOKEN, not HASH to avoid a conflict with the <HASH>
* start condition in the lexer. */
-%token COMMA_FINAL DEFINED ELIF_EXPANDED HASH_TOKEN HASH_DEFINE FUNC_IDENTIFIER OBJ_IDENTIFIER HASH_ELIF HASH_ELSE HASH_ENDIF HASH_IF HASH_IFDEF HASH_IFNDEF HASH_LINE HASH_UNDEF HASH_VERSION IDENTIFIER IF_EXPANDED INTEGER INTEGER_STRING LINE_EXPANDED NEWLINE OTHER PLACEHOLDER SPACE
+%token COMMA_FINAL DEFINED ELIF_EXPANDED HASH_TOKEN HASH_DEFINE FUNC_IDENTIFIER OBJ_IDENTIFIER HASH_ELIF HASH_ELSE HASH_ENDIF HASH_ERROR HASH_IF HASH_IFDEF HASH_IFNDEF HASH_LINE HASH_PRAGMA HASH_UNDEF HASH_VERSION HASH_GARBAGE IDENTIFIER IF_EXPANDED INTEGER INTEGER_STRING LINE_EXPANDED NEWLINE OTHER PLACEHOLDER SPACE
%token PASTE
%type <ival> INTEGER operator SPACE integer_constant
%type <expression_value> expression
-%type <str> IDENTIFIER FUNC_IDENTIFIER OBJ_IDENTIFIER INTEGER_STRING OTHER
+%type <str> IDENTIFIER FUNC_IDENTIFIER OBJ_IDENTIFIER INTEGER_STRING OTHER HASH_ERROR HASH_PRAGMA
%type <string_list> identifier_list
%type <token> preprocessing_token conditional_token
%type <token_list> pp_tokens replacement_list text_line conditional_tokens
@@ -197,27 +197,14 @@ input:
;
line:
- control_line {
- ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "\n");
- }
-| HASH_LINE {
- glcpp_parser_resolve_implicit_version(parser);
- } pp_tokens NEWLINE {
-
- if (parser->skip_stack == NULL ||
- parser->skip_stack->type == SKIP_NO_SKIP)
- {
- _glcpp_parser_expand_and_lex_from (parser,
- LINE_EXPANDED, $3);
- }
- }
+ control_line
+| SPACE control_line
| text_line {
_glcpp_parser_print_expanded_token_list (parser, $1);
ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "\n");
ralloc_free ($1);
}
| expanded_line
-| HASH_TOKEN non_directive
;
expanded_line:
@@ -264,27 +251,45 @@ define:
;
control_line:
- HASH_DEFINE {
+ control_line_success {
+ ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "\n");
+ }
+| control_line_error
+| HASH_TOKEN HASH_LINE {
+ glcpp_parser_resolve_implicit_version(parser);
+ } pp_tokens NEWLINE {
+
+ if (parser->skip_stack == NULL ||
+ parser->skip_stack->type == SKIP_NO_SKIP)
+ {
+ _glcpp_parser_expand_and_lex_from (parser,
+ LINE_EXPANDED, $4);
+ }
+ }
+;
+
+control_line_success:
+ HASH_TOKEN HASH_DEFINE {
glcpp_parser_resolve_implicit_version(parser);
} define
-| HASH_UNDEF {
+| HASH_TOKEN HASH_UNDEF {
glcpp_parser_resolve_implicit_version(parser);
} IDENTIFIER NEWLINE {
macro_t *macro;
- if (strcmp("__LINE__", $3) == 0
- || strcmp("__FILE__", $3) == 0
- || strcmp("__VERSION__", $3) == 0)
+ if (strcmp("__LINE__", $4) == 0
+ || strcmp("__FILE__", $4) == 0
+ || strcmp("__VERSION__", $4) == 0)
glcpp_error(& @1, parser, "Built-in (pre-defined)"
" macro names can not be undefined.");
- macro = hash_table_find (parser->defines, $3);
+ macro = hash_table_find (parser->defines, $4);
if (macro) {
- hash_table_remove (parser->defines, $3);
+ hash_table_remove (parser->defines, $4);
ralloc_free (macro);
}
- ralloc_free ($3);
+ ralloc_free ($4);
}
-| HASH_IF {
+| HASH_TOKEN HASH_IF {
glcpp_parser_resolve_implicit_version(parser);
} conditional_tokens NEWLINE {
/* Be careful to only evaluate the 'if' expression if
@@ -298,7 +303,7 @@ control_line:
parser->skip_stack->type == SKIP_NO_SKIP)
{
_glcpp_parser_expand_and_lex_from (parser,
- IF_EXPANDED, $3);
+ IF_EXPANDED, $4);
}
else
{
@@ -306,7 +311,7 @@ control_line:
parser->skip_stack->type = SKIP_TO_ENDIF;
}
}
-| HASH_IF NEWLINE {
+| HASH_TOKEN HASH_IF NEWLINE {
/* #if without an expression is only an error if we
* are not skipping */
if (parser->skip_stack == NULL ||
@@ -316,21 +321,21 @@ control_line:
}
_glcpp_parser_skip_stack_push_if (parser, & @1, 0);
}
-| HASH_IFDEF {
+| HASH_TOKEN HASH_IFDEF {
glcpp_parser_resolve_implicit_version(parser);
} IDENTIFIER junk NEWLINE {
- macro_t *macro = hash_table_find (parser->defines, $3);
- ralloc_free ($3);
+ macro_t *macro = hash_table_find (parser->defines, $4);
+ ralloc_free ($4);
_glcpp_parser_skip_stack_push_if (parser, & @1, macro != NULL);
}
-| HASH_IFNDEF {
+| HASH_TOKEN HASH_IFNDEF {
glcpp_parser_resolve_implicit_version(parser);
} IDENTIFIER junk NEWLINE {
- macro_t *macro = hash_table_find (parser->defines, $3);
- ralloc_free ($3);
- _glcpp_parser_skip_stack_push_if (parser, & @2, macro == NULL);
+ macro_t *macro = hash_table_find (parser->defines, $4);
+ ralloc_free ($4);
+ _glcpp_parser_skip_stack_push_if (parser, & @3, macro == NULL);
}
-| HASH_ELIF conditional_tokens NEWLINE {
+| HASH_TOKEN HASH_ELIF conditional_tokens NEWLINE {
/* Be careful to only evaluate the 'elif' expression
* if we are not skipping. When we are skipping, we
* simply change to a 0-valued 'elif' on the skip
@@ -342,7 +347,7 @@ control_line:
parser->skip_stack->type == SKIP_TO_ELSE)
{
_glcpp_parser_expand_and_lex_from (parser,
- ELIF_EXPANDED, $2);
+ ELIF_EXPANDED, $3);
}
else if (parser->skip_stack &&
parser->skip_stack->has_else)
@@ -355,7 +360,7 @@ control_line:
"elif", 0);
}
}
-| HASH_ELIF NEWLINE {
+| HASH_TOKEN HASH_ELIF NEWLINE {
/* #elif without an expression is an error unless we
* are skipping. */
if (parser->skip_stack &&
@@ -375,7 +380,7 @@ control_line:
glcpp_warning(& @1, parser, "ignoring illegal #elif without expression");
}
}
-| HASH_ELSE { parser->lexing_directive = 1; } NEWLINE {
+| HASH_TOKEN HASH_ELSE { parser->lexing_directive = 1; } NEWLINE {
if (parser->skip_stack &&
parser->skip_stack->has_else)
{
@@ -388,24 +393,36 @@ control_line:
parser->skip_stack->has_else = true;
}
}
-| HASH_ENDIF {
+| HASH_TOKEN HASH_ENDIF {
_glcpp_parser_skip_stack_pop (parser, & @1);
} NEWLINE
-| HASH_VERSION integer_constant NEWLINE {
+| HASH_TOKEN HASH_VERSION integer_constant NEWLINE {
if (parser->version_resolved) {
glcpp_error(& @1, parser, "#version must appear on the first line");
}
- _glcpp_parser_handle_version_declaration(parser, $2, NULL, true);
+ _glcpp_parser_handle_version_declaration(parser, $3, NULL, true);
}
-| HASH_VERSION integer_constant IDENTIFIER NEWLINE {
+| HASH_TOKEN HASH_VERSION integer_constant IDENTIFIER NEWLINE {
if (parser->version_resolved) {
glcpp_error(& @1, parser, "#version must appear on the first line");
}
- _glcpp_parser_handle_version_declaration(parser, $2, $3, true);
+ _glcpp_parser_handle_version_declaration(parser, $3, $4, true);
}
| HASH_TOKEN NEWLINE {
glcpp_parser_resolve_implicit_version(parser);
}
+| HASH_TOKEN HASH_PRAGMA NEWLINE {
+ ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "#%s", $2);
+ }
+;
+
+control_line_error:
+ HASH_TOKEN HASH_ERROR NEWLINE {
+ glcpp_error(& @1, parser, "#%s", $2);
+ }
+| HASH_TOKEN HASH_GARBAGE pp_tokens NEWLINE {
+ glcpp_error (& @1, parser, "Illegal non-directive after #");
+ }
;
integer_constant:
@@ -617,12 +634,6 @@ text_line:
| pp_tokens NEWLINE
;
-non_directive:
- pp_tokens NEWLINE {
- yyerror (& @1, parser, "Invalid tokens after #");
- }
-;
-
replacement_list:
/* empty */ { $$ = NULL; }
| pp_tokens
@@ -1313,7 +1324,9 @@ glcpp_parser_create (const struct gl_extensions *extensions, gl_api api)
parser->active = NULL;
parser->lexing_directive = 0;
parser->space_tokens = 1;
- parser->last_token_was_newline = 0;
+ parser->last_token_was_newline = 0;
+ parser->last_token_was_space = 0;
+ parser->first_non_space_token_this_line = 1;
parser->newline_as_space = 0;
parser->in_control_line = 0;
parser->paren_count = 0;