gskslpreprocessor: Return fatalness of parsing

Instead of relying on parsing functions to return FALSE on error, we
record that parsing failed inside the preprocessor object and continue
parsing (potentially using dummy objects as the result).

That way, we keep parsing and can emit potentially useful error messages
for the rest of the document.

Now we just need to implement that mentality.
This commit is contained in:
Benjamin Otte
2017-09-27 17:18:53 +02:00
parent 2bceaedd37
commit a2aaf2b90e
5 changed files with 21 additions and 12 deletions

View File

@@ -196,7 +196,9 @@ gsk_sl_compiler_compile (GskSlCompiler *compiler,
preproc = gsk_sl_preprocessor_new (compiler, source);
if (!gsk_sl_program_parse (program, preproc))
gsk_sl_program_parse (program, preproc);
if (gsk_sl_preprocessor_has_fatal_error (preproc))
{
g_object_unref (program);
program = NULL;

View File

@@ -39,6 +39,7 @@ struct _GskSlPreprocessor
GskSlTokenizer *tokenizer;
GArray *tokens;
GHashTable *defines;
gboolean fatal_error;
};
/* API */
@@ -111,6 +112,12 @@ gsk_sl_preprocessor_unref (GskSlPreprocessor *preproc)
g_slice_free (GskSlPreprocessor, preproc);
}
gboolean
gsk_sl_preprocessor_has_fatal_error (GskSlPreprocessor *preproc)
{
return preproc->fatal_error;
}
static gboolean
gsk_sl_preprocessor_next_token (GskSlPreprocessor *preproc,
GskSlPpToken *pp,
@@ -375,6 +382,8 @@ gsk_sl_preprocessor_emit_error (GskSlPreprocessor *preproc,
const GskCodeLocation *location,
const GError *error)
{
preproc->fatal_error |= fatal;
g_printerr ("%3zu:%2zu: %s: %s\n",
location->lines + 1, location->line_bytes,
fatal ? "error" : "warn",

View File

@@ -31,6 +31,7 @@ GskSlPreprocessor * gsk_sl_preprocessor_new (GskSlCompiler
GskSlPreprocessor * gsk_sl_preprocessor_ref (GskSlPreprocessor *preproc);
void gsk_sl_preprocessor_unref (GskSlPreprocessor *preproc);
gboolean gsk_sl_preprocessor_has_fatal_error (GskSlPreprocessor *preproc);
const GskSlToken * gsk_sl_preprocessor_get (GskSlPreprocessor *preproc);
const GskCodeLocation * gsk_sl_preprocessor_get_location (GskSlPreprocessor *preproc);
void gsk_sl_preprocessor_consume (GskSlPreprocessor *preproc,

View File

@@ -136,7 +136,7 @@ gsk_sl_program_parse_variable (GskSlProgram *program,
return TRUE;
}
static gboolean
static void
gsk_sl_program_parse_declaration (GskSlProgram *program,
GskSlScope *scope,
GskSlPreprocessor *preproc)
@@ -155,7 +155,7 @@ gsk_sl_program_parse_declaration (GskSlProgram *program,
if (type == NULL)
{
gsk_sl_preprocessor_consume (preproc, program);
return FALSE;
return;
}
token = gsk_sl_preprocessor_get (preproc);
@@ -170,13 +170,13 @@ gsk_sl_program_parse_declaration (GskSlProgram *program,
gsk_sl_preprocessor_consume (preproc, program);
}
gsk_sl_type_unref (type);
return success;
return;
}
else if (!gsk_sl_token_is (token, GSK_SL_TOKEN_IDENTIFIER))
{
gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected a variable name");
gsk_sl_type_unref (type);
return FALSE;
return;
}
name = g_strdup (token->str);
@@ -204,24 +204,21 @@ gsk_sl_program_parse_declaration (GskSlProgram *program,
g_free (name);
return success;
return;
}
gboolean
void
gsk_sl_program_parse (GskSlProgram *program,
GskSlPreprocessor *preproc)
{
const GskSlToken *token;
gboolean success = TRUE;
for (token = gsk_sl_preprocessor_get (preproc);
!gsk_sl_token_is (token, GSK_SL_TOKEN_EOF);
token = gsk_sl_preprocessor_get (preproc))
{
success &= gsk_sl_program_parse_declaration (program, program->scope, preproc);
gsk_sl_program_parse_declaration (program, program->scope, preproc);
}
return success;
}
void

View File

@@ -24,7 +24,7 @@
G_BEGIN_DECLS
gboolean gsk_sl_program_parse (GskSlProgram *program,
void gsk_sl_program_parse (GskSlProgram *program,
GskSlPreprocessor *preproc);
G_END_DECLS