summaryrefslogtreecommitdiff
path: root/GLESv2/yagl_glsl_lexer.l
diff options
context:
space:
mode:
authorStanislav Vorobiov <s.vorobiov@samsung.com>2014-02-26 18:24:40 +0400
committerStanislav Vorobiov <s.vorobiov@samsung.com>2014-03-01 13:02:58 +0400
commit65d0d66fdc30d351998192fdb4014a848eff9a78 (patch)
tree5548eb8c116d85016e085dd75668a9e891412808 /GLESv2/yagl_glsl_lexer.l
parenta4cc60b70f8e04ad3c24f4899a391b8febe0f46b (diff)
downloademulator-yagl-65d0d66fdc30d351998192fdb4014a848eff9a78.tar.gz
emulator-yagl-65d0d66fdc30d351998192fdb4014a848eff9a78.tar.bz2
emulator-yagl-65d0d66fdc30d351998192fdb4014a848eff9a78.zip
YaGL: Using flex/bison-based GLSL ES patcher
Our old method of GLSL ES patching via simple tokenization isn't feasible for GLESv3 support, there're many GLSL ES and desktop GLSL variations and we must handle all of them. Also, we would like to have full shader validation in the future, thus, we can just extend this parser instead of introducing a new one Change-Id: Ib505a0b22c6dfa810b99a7353b15e8800ff5b55f
Diffstat (limited to 'GLESv2/yagl_glsl_lexer.l')
-rw-r--r--GLESv2/yagl_glsl_lexer.l308
1 files changed, 308 insertions, 0 deletions
diff --git a/GLESv2/yagl_glsl_lexer.l b/GLESv2/yagl_glsl_lexer.l
new file mode 100644
index 0000000..a434be9
--- /dev/null
+++ b/GLESv2/yagl_glsl_lexer.l
@@ -0,0 +1,308 @@
+%{
+#include <GL/gl.h>
+#include "yagl_glsl_state.h"
+#include "yagl_malloc.h"
+
+#define YY_NO_INPUT
+
+#define YY_INPUT(buf, result, max_size) \
+ result = string_input(buf, max_size, yyscanner);
+
+static yy_size_t string_input(char *buf, yy_size_t max_size, yyscan_t yyscanner);
+%}
+
+%option bison-bridge reentrant noyywrap
+%option nounput
+%option never-interactive
+%option prefix="yagl_glsl_lexer_"
+%option extra-type="struct yagl_glsl_state *"
+
+%x COMMENT PP
+
+WS [ \r\t\v\f]
+PRECISION "lowp"|"mediump"|"highp"|"precision"[^;\n]+;?
+GLEXT "GL_"[0-9a-zA-Z]+"_"[0-9a-zA-Z_]+
+CONTROL [()\[\]{},;?:/%*&|^!+\-=<>\.]
+STRING [^ \r\t\v\f\n()\[\]{},;?:/%*&|^!+\-=<>\.]+
+
+%%
+
+"//"[^\n]* {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_comment(state, strlen(yytext));
+}
+
+"/*" {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ BEGIN(COMMENT);
+ yagl_glsl_state_new_comment(state, strlen(yytext));
+}
+
+^{WS}*#{WS}*version {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ BEGIN(PP);
+ yagl_glsl_state_new_str_token(state, yylval, yytext);
+ return TOK_VERSION;
+}
+
+^{WS}*#{WS}*define {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ BEGIN(PP);
+ yagl_glsl_state_new_str_token(state, yylval, yytext);
+ return TOK_DEFINE;
+}
+
+[\n]+ {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_pending(state, yytext);
+}
+
+{WS}+ {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_pending(state, yytext);
+}
+
+"gl_MaxVertexUniformVectors" {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_str_token(state, yylval, yytext);
+ return TOK_MAXVERTEXUNIFORMVECTORS;
+}
+
+"gl_MaxFragmentUniformVectors" {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_str_token(state, yylval, yytext);
+ return TOK_MAXFRAGMENTUNIFORMVECTORS;
+}
+
+"gl_MaxVaryingVectors" {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_str_token(state, yylval, yytext);
+ return TOK_MAXVARYINGVECTORS;
+}
+
+"attribute" {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_str_token(state, yylval, yytext);
+ return TOK_ATTRIBUTE;
+}
+
+"varying" {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_str_token(state, yylval, yytext);
+ return TOK_VARYING;
+}
+
+"texture1D" {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_str_token(state, yylval, yytext);
+ return TOK_TEXTURE;
+}
+
+"texture2D" {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_str_token(state, yylval, yytext);
+ return TOK_TEXTURE;
+}
+
+"texture3D" {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_str_token(state, yylval, yytext);
+ return TOK_TEXTURE;
+}
+
+"textureCube" {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_str_token(state, yylval, yytext);
+ return TOK_TEXTURE;
+}
+
+"gl_FragColor" {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_str_token(state, yylval, yytext);
+ return TOK_GLFRAGCOLOR;
+}
+
+{GLEXT} {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_str_token(state, yylval, yytext);
+ return TOK_GLEXT;
+}
+
+{PRECISION} {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_str_token(state, yylval, yytext);
+ return TOK_PRECISION;
+}
+
+{CONTROL} {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_pending(state, yytext);
+}
+
+{STRING} {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_pending(state, yytext);
+}
+
+<PP>\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}+ {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_pending(state, yytext);
+}
+
+<PP>[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" {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_str_token(state, yylval, yytext);
+ return TOK_ES;
+}
+
+<PP>{GLEXT} {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_str_token(state, yylval, yytext);
+ return TOK_GLEXT;
+}
+
+<PP>{PRECISION} {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_str_token(state, yylval, yytext);
+ return TOK_PRECISION;
+}
+
+<PP>{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} {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_str_token(state, yylval, yytext);
+ return TOK_STRING;
+}
+
+<COMMENT>[^*\n]* {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_comment(state, strlen(yytext));
+}
+
+<COMMENT>[^*\n]*\n {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_comment(state, strlen(yytext) - 1);
+ yagl_glsl_state_new_pending(state, "\n");
+}
+
+<COMMENT>"*"+[^*/\n]* {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_comment(state, strlen(yytext));
+}
+
+<COMMENT>"*"+[^*/\n]*\n {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ yagl_glsl_state_new_comment(state, strlen(yytext) - 1);
+ yagl_glsl_state_new_pending(state, "\n");
+}
+
+<COMMENT>"*"+"/" {
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ BEGIN(INITIAL);
+ yagl_glsl_state_new_comment(state, strlen(yytext));
+}
+
+%%
+
+static yy_size_t string_input(char *buf, yy_size_t max_size, yyscan_t yyscanner)
+{
+ struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+ int rem = state->source_len - state->source_pos;
+ int num_read = (rem < max_size) ? rem : max_size;
+
+ memcpy(buf, state->source + state->source_pos, num_read);
+
+ state->source_pos += num_read;
+
+ return num_read;
+}
+
+//extern int yagl_glsl_debug;
+
+int yagl_glsl_state_init(struct yagl_glsl_state *state,
+ GLenum shader_type,
+ const char *source,
+ int source_len,
+ const char **extensions,
+ int num_extensions,
+ int es3_supported)
+{
+ yyscan_t scanner = NULL;
+
+ memset(state, 0, sizeof(*state));
+
+ //yagl_glsl_debug = 1;
+
+ if (yagl_glsl_lexer_lex_init_extra(state, &scanner)) {
+ return 0;
+ }
+
+ state->shader_type = shader_type;
+ state->source = source;
+ state->source_len = source_len;
+ state->extensions = extensions;
+ state->num_extensions = num_extensions;
+ state->es3_supported = es3_supported;
+ state->scanner = scanner;
+ state->token_index = 1;
+
+ yagl_glsl_state_set_version(state, 120, 0);
+
+ yagl_vector_init(&state->header, sizeof(char), 0);
+ yagl_vector_init(&state->output, sizeof(char), 0);
+ yagl_list_init(&state->pending_list);
+ yagl_vector_init(&state->pending, sizeof(char), 0);
+ yagl_vector_init(&state->strings, sizeof(char*), 0);
+
+ return 1;
+}
+
+void yagl_glsl_state_cleanup(struct yagl_glsl_state *state)
+{
+ yyscan_t scanner = state->scanner;
+ int i;
+ char **tmp;
+ struct yagl_glsl_pending *it, *tmp_it;
+
+ tmp = yagl_vector_data(&state->strings);
+
+ for (i = 0; i < yagl_vector_size(&state->strings); ++i) {
+ free(*(tmp + i));
+ }
+
+ yagl_vector_cleanup(&state->strings);
+
+ yagl_vector_cleanup(&state->pending);
+
+ yagl_list_for_each_safe(struct yagl_glsl_pending,
+ it,
+ tmp_it,
+ &state->pending_list, list) {
+ yagl_list_remove(&it->list);
+ yagl_free(it);
+ }
+
+ yagl_vector_cleanup(&state->output);
+
+ yagl_vector_cleanup(&state->header);
+
+ yagl_glsl_lexer_lex_destroy(scanner);
+}