From fad4112d78992f90c34e4839dde3196c6f87f721 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Thu, 28 Sep 2017 13:34:46 +0200 Subject: [PATCH] gsksl: Introduce gsk_sl_preprocessor_sync() Instead of just returning after an error an continuing to parse wherever, use gsk_sl_preprocessor_sync() to find the next point in the token stream that looks like a useful way to continue parsing. --- gsk/gskslfunction.c | 6 +++--- gsk/gskslnode.c | 8 +++++--- gsk/gskslpointertype.c | 8 +++++--- gsk/gskslpreprocessor.c | 32 ++++++++++++++++++++++++++++++++ gsk/gskslpreprocessorprivate.h | 2 ++ gsk/gskslprogram.c | 8 +++++--- 6 files changed, 52 insertions(+), 12 deletions(-) diff --git a/gsk/gskslfunction.c b/gsk/gskslfunction.c index f51aeac599..dd914259c3 100644 --- a/gsk/gskslfunction.c +++ b/gsk/gskslfunction.c @@ -389,7 +389,7 @@ gsk_sl_function_new_parse (GskSlScope *scope, if (!gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_PAREN)) { gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected a closing \")\""); - return (GskSlFunction *) function; + gsk_sl_preprocessor_sync (preproc, GSK_SL_TOKEN_RIGHT_PAREN); } gsk_sl_preprocessor_consume (preproc, (GskSlNode *) function); @@ -421,8 +421,8 @@ gsk_sl_function_new_parse (GskSlScope *scope, if (!gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_BRACE)) { - gsk_sl_preprocessor_error (preproc, SYNTAX, "Missing closing \"}\" at end."); - return (GskSlFunction *) function; + gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected closing \"}\" at end of function."); + gsk_sl_preprocessor_sync (preproc, GSK_SL_TOKEN_RIGHT_BRACE); } gsk_sl_preprocessor_consume (preproc, (GskSlNode *) function); diff --git a/gsk/gskslnode.c b/gsk/gskslnode.c index 8f50830a84..32ae89f890 100644 --- a/gsk/gskslnode.c +++ b/gsk/gskslnode.c @@ -472,9 +472,11 @@ gsk_sl_node_parse_statement (GskSlScope *scope, token = gsk_sl_preprocessor_get (preproc); if (!gsk_sl_token_is (token, GSK_SL_TOKEN_SEMICOLON)) - gsk_sl_preprocessor_error (preproc, SYNTAX, "No semicolon at end of statement."); - else - gsk_sl_preprocessor_consume (preproc, (GskSlNode *) node); + { + gsk_sl_preprocessor_error (preproc, SYNTAX, "No semicolon at end of statement."); + gsk_sl_preprocessor_sync (preproc, GSK_SL_TOKEN_SEMICOLON); + } + gsk_sl_preprocessor_consume (preproc, (GskSlNode *) node); return node; } diff --git a/gsk/gskslpointertype.c b/gsk/gskslpointertype.c index 5261f7f08f..96766fed37 100644 --- a/gsk/gskslpointertype.c +++ b/gsk/gskslpointertype.c @@ -332,9 +332,11 @@ gsk_sl_decoration_list_parse (GskSlScope *scope, token = gsk_sl_preprocessor_get (preproc); if (gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_PAREN)) - gsk_sl_preprocessor_consume (preproc, NULL); - else - gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected closing \")\" at end of layout specifier"); + { + gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected closing \")\" at end of layout specifier"); + gsk_sl_preprocessor_sync (preproc, GSK_SL_TOKEN_RIGHT_PAREN); + } + gsk_sl_preprocessor_consume (preproc, NULL); break; default: diff --git a/gsk/gskslpreprocessor.c b/gsk/gskslpreprocessor.c index ca39e79d43..836875033e 100644 --- a/gsk/gskslpreprocessor.c +++ b/gsk/gskslpreprocessor.c @@ -376,6 +376,38 @@ gsk_sl_preprocessor_consume (GskSlPreprocessor *preproc, g_array_remove_index (preproc->tokens, 0); } +void +gsk_sl_preprocessor_sync (GskSlPreprocessor *preproc, + GskSlTokenType token_type) +{ + const GskSlToken *token; + + for (token = gsk_sl_preprocessor_get (preproc); + !gsk_sl_token_is (token, GSK_SL_TOKEN_EOF) && !gsk_sl_token_is (token, token_type); + token = gsk_sl_preprocessor_get (preproc)) + { + if (gsk_sl_token_is (token, GSK_SL_TOKEN_LEFT_BRACE)) + { + gsk_sl_preprocessor_consume (preproc, NULL); + gsk_sl_preprocessor_sync (preproc, GSK_SL_TOKEN_RIGHT_BRACE); + } + else if (gsk_sl_token_is (token, GSK_SL_TOKEN_LEFT_BRACKET)) + { + gsk_sl_preprocessor_consume (preproc, NULL); + gsk_sl_preprocessor_sync (preproc, GSK_SL_TOKEN_RIGHT_BRACKET); + } + else if (gsk_sl_token_is (token, GSK_SL_TOKEN_LEFT_PAREN)) + { + gsk_sl_preprocessor_consume (preproc, NULL); + gsk_sl_preprocessor_sync (preproc, GSK_SL_TOKEN_RIGHT_PAREN); + } + else + { + gsk_sl_preprocessor_consume (preproc, NULL); + } + } +} + void gsk_sl_preprocessor_emit_error (GskSlPreprocessor *preproc, gboolean fatal, diff --git a/gsk/gskslpreprocessorprivate.h b/gsk/gskslpreprocessorprivate.h index b6544cca73..13755d11d6 100644 --- a/gsk/gskslpreprocessorprivate.h +++ b/gsk/gskslpreprocessorprivate.h @@ -37,6 +37,8 @@ const GskCodeLocation * gsk_sl_preprocessor_get_location (GskSlPreprocess void gsk_sl_preprocessor_consume (GskSlPreprocessor *preproc, gpointer consumer); +void gsk_sl_preprocessor_sync (GskSlPreprocessor *preproc, + GskSlTokenType token); void gsk_sl_preprocessor_emit_error (GskSlPreprocessor *preproc, gboolean fatal, const GskCodeLocation *location, diff --git a/gsk/gskslprogram.c b/gsk/gskslprogram.c index 47b68bed5c..3d47dd6f14 100644 --- a/gsk/gskslprogram.c +++ b/gsk/gskslprogram.c @@ -119,9 +119,11 @@ gsk_sl_program_parse_variable (GskSlProgram *program, } if (!gsk_sl_token_is (token, GSK_SL_TOKEN_SEMICOLON)) - gsk_sl_preprocessor_error (preproc, SYNTAX, "No semicolon at end of variable declaration."); - else - gsk_sl_preprocessor_consume (preproc, NULL); + { + gsk_sl_preprocessor_error (preproc, SYNTAX, "No semicolon at end of variable declaration."); + gsk_sl_preprocessor_sync (preproc, GSK_SL_TOKEN_SEMICOLON); + } + gsk_sl_preprocessor_consume (preproc, NULL); pointer_type = gsk_sl_pointer_type_new (type, FALSE, decoration->values[GSK_SL_DECORATION_CALLER_ACCESS].value); variable = gsk_sl_variable_new (pointer_type, g_strdup (name), value, decoration->values[GSK_SL_DECORATION_CONST].set);