diff options
author | Carl Worth <[email protected]> | 2014-06-25 12:20:22 -0700 |
---|---|---|
committer | Carl Worth <[email protected]> | 2014-07-29 15:11:50 -0700 |
commit | f062f0506a5b827667b7eb52136d8420b7e8113b (patch) | |
tree | 6f758f87be25365ee6a72c2f68776f4f54afbd7e /src/glsl/glcpp/tests | |
parent | dfdf9dc082cbab332457ea2dbe012eeb0d164ce4 (diff) |
glsl/glcpp: Correctly parse directives with intervening comments
It's legal (though highly bizarre) for a pre-processor directive to look like
this:
# /* why? */ define FOO bar
This behavior comes about since the specification defines separate logical
phases in a precise order, and comment-removal occurs in a phase before the
identification of directives.
Our implementation does not use an actual separate phase for comment removal,
so some extra care is necessary to correctly parse this. What we want is for
'#' to introduce a directive iff it is the first token on a line, (ignoring
whitespace and comments). Previously, we had a lexical rule that worked only
for whitespace (not comments) with the following regular expression to find a
directive-introducing '#' at the beginning of a line:
HASH ^{HSPACE}*#{HSPACE}*
In this commit, we switch to instead use a simple literal match of '#' to
return a HASH_TOKEN token and add a new <HASH> start condition for whenever
the HASH_TOKEN is the first non-space token of a line. This requires the
addition of the new bit of state: first_non_space_token_this_line.
This approach has a couple of implications on the glcpp parser:
1. The parser now sees two separate tokens, (such as HASH_TOKEN and
HASH_DEFINE) where it previously saw one token (HASH_DEFINE) for
the sequence "#define". This is a straightforward change throughout
the grammar.
2. The parser may now see a SPACE token before the HASH_TOKEN token of
a directive. Previously the lexical regular expression for {HASH}
would eat up the space and there would be no SPACE token.
This second implication is a bit of a nuisance for the parser. It causes a
SPACE token to appear in a production of the grammar with the following two
definitions of a control_line:
control_line
SPACE control_line
This is really ugly, since normally a space would simply be a token
separator, so it wouldn't appear in the tokens of a production. This leads to
a further problem with interleaved spaces and comments:
/* ... */ /* ... */ #define /* ..*/
For this, we must not return several consecutive SPACE tokens, or else we would need an arbitrary number of new productions:
SPACE SPACE control_line
SPACE SPACE SPACE control_line
ad nauseam
To avoid this problem, in this commit we also change the lexer to emit only a
single SPACE token for any series of consecutive spaces, (whether from actual
whitespace or comments). For this compression, we add a new bit of parser
state: last_token_was_space. And we also update the expected results of all
necessary test cases for the new compression of space tokens.
Fortunately, the compression of spaces should not lead to any semantic changes
in terms of what the eventual GLSL compiler sees.
So there's a lot happening in this commit, (particularly for such a tiny
feature). But fortunately, the lexer itself is looking cleaner than ever. The
only ugly bit is all the state updating, but it is at least isolated to a
single shared function.
Of course, a new "make check" test is added for the new feature, (directives
with comments and whitespace interleaved in many combinations).
And this commit fixes the following Khronos GLES3 CTS tests:
function_definition_with_comments_vertex
function_definition_with_comments_fragment
Reviewed-by: Jordan Justen <[email protected]>
Diffstat (limited to 'src/glsl/glcpp/tests')
13 files changed, 56 insertions, 17 deletions
diff --git a/src/glsl/glcpp/tests/000-content-with-spaces.c.expected b/src/glsl/glcpp/tests/000-content-with-spaces.c.expected index f49870f7aa7..00791910ed5 100644 --- a/src/glsl/glcpp/tests/000-content-with-spaces.c.expected +++ b/src/glsl/glcpp/tests/000-content-with-spaces.c.expected @@ -1 +1 @@ - this is four tokens with spaces + this is four tokens with spaces diff --git a/src/glsl/glcpp/tests/090-hash-error.c.expected b/src/glsl/glcpp/tests/090-hash-error.c.expected index 32954f7380e..876a6ea9cc5 100644 --- a/src/glsl/glcpp/tests/090-hash-error.c.expected +++ b/src/glsl/glcpp/tests/090-hash-error.c.expected @@ -1,2 +1 @@ 0:1(1): preprocessor error: #error human error - diff --git a/src/glsl/glcpp/tests/091-hash-line.c.expected b/src/glsl/glcpp/tests/091-hash-line.c.expected index d6831da384e..ac9ab252f1e 100644 --- a/src/glsl/glcpp/tests/091-hash-line.c.expected +++ b/src/glsl/glcpp/tests/091-hash-line.c.expected @@ -3,13 +3,9 @@ 1:0(1): preprocessor error: #error source 1, line 0 error 2:30(1): preprocessor error: #error source 2, line 30 error #line 0 - #line 25 - #line 0 1 - #line 30 2 - #line 45 2 diff --git a/src/glsl/glcpp/tests/100-macro-with-colon.c.expected b/src/glsl/glcpp/tests/100-macro-with-colon.c.expected index b4360784ee0..09f1f417bdd 100644 --- a/src/glsl/glcpp/tests/100-macro-with-colon.c.expected +++ b/src/glsl/glcpp/tests/100-macro-with-colon.c.expected @@ -2,6 +2,6 @@ switch (1) { - case 1 + 2: - break; + case 1 + 2: + break; } diff --git a/src/glsl/glcpp/tests/108-no-space-after-hash-version.c.expected b/src/glsl/glcpp/tests/108-no-space-after-hash-version.c.expected index 462166c9801..4f4243f947f 100644 --- a/src/glsl/glcpp/tests/108-no-space-after-hash-version.c.expected +++ b/src/glsl/glcpp/tests/108-no-space-after-hash-version.c.expected @@ -1 +1 @@ -0:1(2): preprocessor error: Invalid tokens after # +0:1(1): preprocessor error: Illegal non-directive after # diff --git a/src/glsl/glcpp/tests/109-no-space-after-hash-line.c.expected b/src/glsl/glcpp/tests/109-no-space-after-hash-line.c.expected index 462166c9801..4f4243f947f 100644 --- a/src/glsl/glcpp/tests/109-no-space-after-hash-line.c.expected +++ b/src/glsl/glcpp/tests/109-no-space-after-hash-line.c.expected @@ -1 +1 @@ -0:1(2): preprocessor error: Invalid tokens after # +0:1(1): preprocessor error: Illegal non-directive after # diff --git a/src/glsl/glcpp/tests/110-no-space-digits-after-hash-elif.c.expected b/src/glsl/glcpp/tests/110-no-space-digits-after-hash-elif.c.expected index 847437c9111..4d93de41dd3 100644 --- a/src/glsl/glcpp/tests/110-no-space-digits-after-hash-elif.c.expected +++ b/src/glsl/glcpp/tests/110-no-space-digits-after-hash-elif.c.expected @@ -1,3 +1,3 @@ -0:2(2): preprocessor error: Invalid tokens after # +0:2(1): preprocessor error: Illegal non-directive after # diff --git a/src/glsl/glcpp/tests/121-comment-bug-72686.c.expected b/src/glsl/glcpp/tests/121-comment-bug-72686.c.expected index 5c484c2fe59..8cb7cb9891f 100644 --- a/src/glsl/glcpp/tests/121-comment-bug-72686.c.expected +++ b/src/glsl/glcpp/tests/121-comment-bug-72686.c.expected @@ -1,2 +1,2 @@ - + diff --git a/src/glsl/glcpp/tests/128-space-before-hash.c.expected b/src/glsl/glcpp/tests/128-space-before-hash.c.expected index 5d44f4161eb..9babb6fb078 100644 --- a/src/glsl/glcpp/tests/128-space-before-hash.c.expected +++ b/src/glsl/glcpp/tests/128-space-before-hash.c.expected @@ -1,6 +1,6 @@ - + #version 300 - #pragma Testing spaces before hash +#pragma Testing spaces before hash #line 3 diff --git a/src/glsl/glcpp/tests/130-define-comment.c.expected b/src/glsl/glcpp/tests/130-define-comment.c.expected index 43d399cafe4..d789e29d5a8 100644 --- a/src/glsl/glcpp/tests/130-define-comment.c.expected +++ b/src/glsl/glcpp/tests/130-define-comment.c.expected @@ -1,2 +1,2 @@ -FOO( bar ) +FOO( bar ) diff --git a/src/glsl/glcpp/tests/132-eof-without-newline-define.c.expected b/src/glsl/glcpp/tests/132-eof-without-newline-define.c.expected index 57dee695714..a3ace0f3966 100644 --- a/src/glsl/glcpp/tests/132-eof-without-newline-define.c.expected +++ b/src/glsl/glcpp/tests/132-eof-without-newline-define.c.expected @@ -1,2 +1,2 @@ -0:1(1): preprocessor error: #define without macro name -0:1(1): preprocessor error: syntax error, unexpected NEWLINE, expecting FUNC_IDENTIFIER or OBJ_IDENTIFIER +0:1(2): preprocessor error: #define without macro name +0:1(2): preprocessor error: syntax error, unexpected NEWLINE, expecting FUNC_IDENTIFIER or OBJ_IDENTIFIER diff --git a/src/glsl/glcpp/tests/134-hash-comment-directive.c b/src/glsl/glcpp/tests/134-hash-comment-directive.c new file mode 100644 index 00000000000..3015f0e886e --- /dev/null +++ b/src/glsl/glcpp/tests/134-hash-comment-directive.c @@ -0,0 +1,22 @@ +/*...*/ # /*...*/ version 300 + /*...*/#/*...*/ extension whatever + /*..*/ # /*..*/ pragma ignored +/**/ # /**/ line 4 + /*...*/# /*...*/ ifdef NOT_DEFINED + /*...*/# /*...*/ else + /*..*/ #/*..*/ endif + /*...*/# /*...*/ ifndef ALSO_NOT_DEFINED + /*...*/# /*...*/ else + /*..*/ #/*..*/ endif +/*...*/ # /*...*/ if 0 + /*...*/#/*...*/ elif 1 + /*..*/ # /*..*/ else + /**/ # /**/ endif + /*...*/# /*...*/ define FOO bar + /*..*/ #/*..*/ define FUNC() baz + /*..*/ # /*..*/ define FUNC2(a,b) b a +FOO +FUNC() +FUNC2(x,y) + + diff --git a/src/glsl/glcpp/tests/134-hash-comment-directive.c.expected b/src/glsl/glcpp/tests/134-hash-comment-directive.c.expected new file mode 100644 index 00000000000..760c960cb62 --- /dev/null +++ b/src/glsl/glcpp/tests/134-hash-comment-directive.c.expected @@ -0,0 +1,22 @@ +#version 300 +#extension whatever +#pragma ignored +#line 4 + + + + + + + + + + + + + +bar +baz +y x + + |