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.
This commit is contained in:
Benjamin Otte
2017-09-28 13:34:46 +02:00
parent c30089a1cb
commit fad4112d78
6 changed files with 52 additions and 12 deletions

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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:

View File

@@ -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,

View File

@@ -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,

View File

@@ -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);