Cleanup GLSL parser/lexer code 88/251688/1
authorLukasz Kostyra <l.kostyra@samsung.com>
Fri, 15 Jan 2021 13:18:34 +0000 (14:18 +0100)
committerLukasz Kostyra <l.kostyra@samsung.com>
Mon, 18 Jan 2021 11:37:13 +0000 (12:37 +0100)
* Improved precision qualifier flushing
* Clarified shift/reduce ambiguities
* Removed deprecated %name_prefix directive warning

Change-Id: Ib740538a67e6f5e6a13a8e35b2caae51874636fa

GLESv2/CMakeLists.txt
GLESv2/yagl_gles2_calls.c
GLESv2/yagl_glsl_lexer.l
GLESv2/yagl_glsl_parser.y

index e8d3496190fecb4ed95a3d1eecfbc85229d8656e..5a97d533f84468647a85c5f87868006355db2a5e 100644 (file)
@@ -28,7 +28,8 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR})
 link_directories(${CMAKE_ARCHIVE_OUTPUT_DIRECTORY})
 
 flex_target(GLESv2 ${CMAKE_CURRENT_SOURCE_DIR}/yagl_glsl_lexer.l ${CMAKE_CURRENT_BINARY_DIR}/yagl_glsl_lexer.c)
-bison_target(GLESv2 ${CMAKE_CURRENT_SOURCE_DIR}/yagl_glsl_parser.y ${CMAKE_CURRENT_BINARY_DIR}/yagl_glsl_parser.c)
+bison_target(GLESv2 ${CMAKE_CURRENT_SOURCE_DIR}/yagl_glsl_parser.y ${CMAKE_CURRENT_BINARY_DIR}/yagl_glsl_parser.c
+             VERBOSE)
 
 add_library(GLESv2 SHARED ${SOURCES} ${FLEX_GLESv2_OUTPUTS} ${BISON_GLESv2_OUTPUTS})
 set_target_properties(GLESv2 PROPERTIES VERSION 2.0 SOVERSION 2)
index 6346fc851c1badae5a0319f8e07b39ec817ad973..38adf7ffa1d4b8fb05b889fec42fa7bdeaf02954 100644 (file)
@@ -1406,6 +1406,7 @@ YAGL_API void glShaderSource(GLuint shader, GLsizei count, const GLchar * const
 
     if (have_strings) {
         uint8_t *tmp_buff;
+        char *print_buff; // LKDEBUG
         int ret;
         int patched_len = 0;
         char *patched_source;
@@ -1425,7 +1426,16 @@ YAGL_API void glShaderSource(GLuint shader, GLsizei count, const GLchar * const
 
         tmp_buff[total_length] = '\0';
 
-        YAGL_LOG_TRACE("orig source = %s", tmp_buff);
+        YAGL_LOG_DEBUG("orig source:", tmp_buff);
+        print_buff = (char*)tmp_buff;
+        while (print_buff)
+        {
+            char *next_line = strchr(print_buff, '\n');
+            if (next_line) *next_line = 0;
+            YAGL_LOG_DEBUG("%s", print_buff);
+            if (next_line) *next_line = '\n';
+            print_buff = next_line ? next_line + 1 : NULL;
+        }
 
         yagl_glsl_state_init(&shader_obj->state,
                              shader_obj->type,
@@ -1443,7 +1453,16 @@ YAGL_API void glShaderSource(GLuint shader, GLsizei count, const GLchar * const
             patched_source = yagl_glsl_state_get_output(&shader_obj->state,
                                                         &patched_len);
 
-            YAGL_LOG_TRACE("patched source = %s", patched_source);
+            YAGL_LOG_DEBUG("patched source:");
+            print_buff = patched_source;
+            while (print_buff)
+            {
+                char *next_line = strchr(print_buff, '\n');
+                if (next_line) *next_line = 0;
+                YAGL_LOG_DEBUG("%s", print_buff);
+                if (next_line) *next_line = '\n';
+                print_buff = next_line ? next_line + 1 : NULL;
+            }
 
             YAGL_LOG_TRACE("Macro and sampler extract summary:");
             YAGL_LOG_TRACE("  Macros:");
@@ -1480,7 +1499,7 @@ YAGL_API void glShaderSource(GLuint shader, GLsizei count, const GLchar * const
             /*
              * Unable to parse source, pass as-is.
              */
-            YAGL_LOG_TRACE("unable to patch shader source, passed as-is");
+            YAGL_LOG_DEBUG("unable to patch shader source, passed as-is");
             yagl_gles2_shader_source(shader_obj,
                                      (GLchar*)tmp_buff,
                                      (GLchar*)tmp_buff,
index 9190c7b3d761826d9c6902b1d58afac2e4de5813..37fc152dc09e4c237e039a2e542f81623c3c60f0 100644 (file)
@@ -17,7 +17,7 @@ static yy_size_t string_input(char *buf, yy_size_t max_size, yyscan_t yyscanner)
 %option prefix="yagl_glsl_lexer_"
 %option extra-type="struct yagl_glsl_state *"
 
-%x COMMENT PP PP_IFDEF PP_IF PP_DEFINE PP_UNDEF UNIFORM PRECISION
+%x COMMENT PP_VERSION PP_IFDEF PP_IF PP_DEFINE PP_UNDEF UNIFORM PRECISION
 
 WS [ \r\t\v\f]
 PRECISION_QUAL "lowp"|"mediump"|"highp"
@@ -40,7 +40,7 @@ STRING [^ \r\t\v\f\n()\[\]{},;?:/%*&|^!+\-=<>\.]+
 
 ^{WS}*#{WS}*version {
     struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
-    BEGIN(PP);
+    BEGIN(PP_VERSION);
     yagl_glsl_state_new_str_token(state, yylval, yytext);
     return TOK_VERSION;
 }
@@ -206,12 +206,6 @@ STRING [^ \r\t\v\f\n()\[\]{},;?:/%*&|^!+\-=<>\.]+
     return TOK_TEXTURE2D;
 }
 
-<PP>"texture2D" {
-    struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
-    yagl_glsl_state_new_str_token(state, yylval, yytext);
-    return TOK_TEXTURE2D;
-}
-
 "texture3DProjLod" {
     struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
     yagl_glsl_state_new_str_token(state, yylval, yytext);
@@ -254,6 +248,12 @@ STRING [^ \r\t\v\f\n()\[\]{},;?:/%*&|^!+\-=<>\.]+
     return TOK_GLFRAGCOLOR;
 }
 
+{PRECISION_QUAL} {
+    struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+    yagl_glsl_state_new_str_token(state, yylval, yytext);
+    return TOK_PRECISION_QUAL;
+}
+
 "precision" {
     struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
     BEGIN(PRECISION);
@@ -278,43 +278,37 @@ STRING [^ \r\t\v\f\n()\[\]{},;?:/%*&|^!+\-=<>\.]+
     yagl_glsl_state_new_pending(state, yytext);
 }
 
-<PP>\n {
+<PP_VERSION>\n {
     struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
     BEGIN(INITIAL);
     yagl_glsl_state_new_str_token(state, yylval, yytext);
     return TOK_EOL;
 }
 
-<PP>{WS}+ {
+<PP_VERSION>{WS}+ {
     struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
     yagl_glsl_state_new_pending(state, yytext);
 }
 
-<PP>[1-9][0-9]* {
+<PP_VERSION>[1-9][0-9]* {
     struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
     yagl_glsl_state_new_integer_token(state, yylval, strtol(yytext, NULL, 10));
     return TOK_INTEGER;
 }
 
-<PP>"es" {
+<PP_VERSION>"es" {
     struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
     yagl_glsl_state_new_str_token(state, yylval, yytext);
     return TOK_ES;
 }
 
-<PP>{PRECISION_ALL} {
-    struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
-    yagl_glsl_state_new_str_token(state, yylval, yytext);
-    return TOK_PRECISION_ALL;
-}
-
-<PP>{CONTROL} {
+<PP_VERSION>{CONTROL} {
     struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
     yagl_glsl_state_new_str_token(state, yylval, yytext);
     return TOK_STRING;
 }
 
-<PP>{STRING} {
+<PP_VERSION>{STRING} {
     struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
     yagl_glsl_state_new_str_token(state, yylval, yytext);
     return TOK_STRING;
@@ -337,12 +331,6 @@ STRING [^ \r\t\v\f\n()\[\]{},;?:/%*&|^!+\-=<>\.]+
     yagl_glsl_state_new_comment(state, strlen(yytext));
 }
 
-<PP_DEFINE>[0-9]+ {
-    struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
-    yagl_glsl_state_new_integer_token(state, yylval, strtol(yytext, NULL, 10));
-    return TOK_INTEGER;
-}
-
 <PP_DEFINE>{STRING} {
     struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
     yagl_glsl_state_new_str_token(state, yylval, yytext);
index 61dbbe275b5e40313d8c1551a0d6afa192539311..08cb11935f6fa86786e525acb744ba19f1ec5fa9 100644 (file)
@@ -2,6 +2,8 @@
 #include <GL/gl.h>
 #include "yagl_glsl_state.h"
 #include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
 #include <string.h>
 
 #undef yyerror
@@ -20,7 +22,7 @@ static int yagl_glsl_lex(union YYSTYPE *val, struct yagl_glsl_state *state)
 %}
 
 %pure-parser
-%name-prefix="yagl_glsl_"
+%name-prefix "yagl_glsl_"
 %lex-param {struct yagl_glsl_state *state}
 %parse-param {struct yagl_glsl_state *state}
 %debug
@@ -90,7 +92,6 @@ static int yagl_glsl_lex(union YYSTYPE *val, struct yagl_glsl_state *state)
 %token <str> TOK_ES
 %token <str> TOK_PRECISION
 %token <str> TOK_PRECISION_QUAL
-%token <str> TOK_PRECISION_ALL
 %token <str> TOK_MAXVERTEXUNIFORMVECTORS
 %token <str> TOK_MAXFRAGMENTUNIFORMVECTORS
 %token <str> TOK_MAXVARYINGVECTORS
@@ -221,14 +222,7 @@ expression
     yagl_glsl_state_flush_pending(state, $1.index);
     yagl_glsl_state_append_output(state, $1.value);
 }
-| TOK_DEFINE TOK_PRECISION_ALL
-{
-    yagl_glsl_state_flush_pending(state, $1.index);
-    yagl_glsl_state_append_output(state, $1.value);
-    yagl_glsl_state_flush_pending(state, $2.index);
-    yagl_glsl_state_append_output(state, $2.value);
-}
-| TOK_DEFINE TOK_STRING TOK_STRING
+| TOK_DEFINE TOK_STRING TOK_STRING TOK_EOL
 {
     yagl_glsl_state_flush_pending(state, $1.index);
     yagl_glsl_state_append_output(state, $1.value);
@@ -236,31 +230,39 @@ expression
     yagl_glsl_state_append_output(state, $2.value);
     yagl_glsl_state_flush_pending(state, $3.index);
     yagl_glsl_state_append_output(state, $3.value);
+    yagl_glsl_state_flush_pending(state, $4.index);
+    yagl_glsl_state_append_output(state, $4.value);
 
-    if (yagl_glsl_state_pp_is_condition_met(state))
-        yagl_glsl_state_pp_add_define_string(state, $2.value, $3.value);
-}
-| TOK_DEFINE TOK_STRING TOK_INTEGER
-{
-    char s[100];
-
-    yagl_glsl_state_flush_pending(state, $1.index);
-    yagl_glsl_state_append_output(state, $1.value);
-    yagl_glsl_state_flush_pending(state, $2.index);
-    yagl_glsl_state_append_output(state, $2.value);
-    yagl_glsl_state_flush_pending(state, $3.index);
-    sprintf(s, "%d", $3.value);
-    yagl_glsl_state_append_output(state, s);
+    if (yagl_glsl_state_pp_is_condition_met(state)) {
+        // Determine if $3 is actually a string or an integer.
+        // We do this here because some shaders could use defines to
+        // place in different types of numbers (ex. floats like PI constant).
+        // However, for preprocessor condition resolution we only care about
+        // integers according to GLSL ES specification.
+        int isint = 1;
+        const char *str = $3.value;
+        while (str) {
+            if (!isdigit(*str) && (*str != '-') && (*str != '+')) {
+                isint = 0;
+            }
+            str++;
+        }
 
-    if (yagl_glsl_state_pp_is_condition_met(state))
-        yagl_glsl_state_pp_add_define_int(state, $2.value, $3.value);
+        if (isint) {
+            yagl_glsl_state_pp_add_define_int(state, $2.value, atoi($3.value));
+        } else {
+            yagl_glsl_state_pp_add_define_string(state, $2.value, $3.value);
+        }
+    }
 }
-| TOK_DEFINE TOK_STRING
+| TOK_DEFINE TOK_STRING TOK_EOL
 {
     yagl_glsl_state_flush_pending(state, $1.index);
     yagl_glsl_state_append_output(state, $1.value);
     yagl_glsl_state_flush_pending(state, $2.index);
     yagl_glsl_state_append_output(state, $2.value);
+    yagl_glsl_state_flush_pending(state, $3.index);
+    yagl_glsl_state_append_output(state, $3.value);
 
     if (yagl_glsl_state_pp_is_condition_met(state))
         yagl_glsl_state_pp_add_define_int(state, $2.value, 1);
@@ -275,11 +277,6 @@ expression
     if (yagl_glsl_state_pp_is_condition_met(state))
         yagl_glsl_state_pp_undef(state, $2.value);
 }
-| TOK_DEFINE
-{
-    yagl_glsl_state_flush_pending(state, $1.index);
-    yagl_glsl_state_append_output(state, $1.value);
-}
 | TOK_PP_IF
 {
     yagl_glsl_state_flush_pending(state, $1.index);
@@ -562,6 +559,14 @@ expression
         yagl_glsl_state_append_output(state, $2.value);
     }
 }
+| TOK_PRECISION_QUAL
+{
+    yagl_glsl_state_flush_pending(state, $1.index);
+    if (!state->patch_precision) {
+        yagl_glsl_state_append_output(state, $1.value);
+    }
+
+}
 | TOK_ES
 {
     yagl_glsl_state_flush_pending(state, $1.index);