[Swfdec-commits] 2 commits - vivified/code

Benjamin Otte company at kemper.freedesktop.org
Fri Apr 25 07:23:06 PDT 2008


 vivified/code/.gitignore                |    1 
 vivified/code/Makefile.am               |   14 +
 vivified/code/vivi_parser.c             |   92 +++++----
 vivified/code/vivi_parser_scanner.c     |  164 +++++++++-------
 vivified/code/vivi_parser_scanner.h     |   64 +++---
 vivified/code/vivi_parser_scanner_lex.h |  315 --------------------------------
 vivified/code/vivi_parser_scanner_lex.l |   65 +++---
 7 files changed, 220 insertions(+), 495 deletions(-)

New commits:
commit 4af8437a718f4674ed5e531f64ed13b29777fdd0
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Apr 25 16:19:16 2008 +0200

    make NONE and EOF the same token

diff --git a/vivified/code/vivi_parser.c b/vivified/code/vivi_parser.c
index bc25fd5..2ed3b93 100644
--- a/vivified/code/vivi_parser.c
+++ b/vivified/code/vivi_parser.c
@@ -272,7 +272,7 @@ parse_automatic_semicolon (ParseData *data)
     return;
 
   token = vivi_parser_scanner_peek_next_token (data->scanner);
-  if (token == TOKEN_BRACE_LEFT || token == TOKEN_EOF)
+  if (token == TOKEN_BRACE_LEFT || token == TOKEN_NONE)
     return;
 
   vivi_parser_error_unexpected (data, TOKEN_SEMICOLON);
@@ -2925,8 +2925,8 @@ parse_program (ParseData *data)
   vivi_parser_start_level (data);
 
   parse_statement_list (data, peek_source_element, parse_source_element,
-      &statement, TOKEN_EOF);
-  parse_token (data, TOKEN_EOF);
+      &statement, TOKEN_NONE);
+  parse_token (data, TOKEN_NONE);
 
   vivi_parser_end_level (data);
   g_assert (data->level == NULL);
diff --git a/vivified/code/vivi_parser_scanner.c b/vivified/code/vivi_parser_scanner.c
index ef0ccc5..67d30b3 100644
--- a/vivified/code/vivi_parser_scanner.c
+++ b/vivified/code/vivi_parser_scanner.c
@@ -97,7 +97,6 @@ static const struct {
 } token_names[] = {
   // special
   { TOKEN_NONE, "NONE" },
-  { TOKEN_EOF, "EOF" },
   { TOKEN_ERROR, "ERROR" },
   { TOKEN_UNKNOWN, "UNKNOWN" },
   { TOKEN_LINE_TERMINATOR, "NEW LINE" },
@@ -244,7 +243,7 @@ vivi_parser_scanner_advance (ViviParserScanner *scanner)
   }
 
   if (scanner->file == NULL) {
-    value->token = TOKEN_EOF;
+    value->token = TOKEN_NONE;
     value->type = VALUE_TYPE_NONE;
     value->column = 0;
     value->position = 0;
@@ -309,7 +308,7 @@ vivi_parser_scanner_set_error_handler (ViviParserScanner *scanner,
 ViviParserScannerToken
 vivi_parser_scanner_get_next_token (ViviParserScanner *scanner)
 {
-  g_return_val_if_fail (VIVI_IS_PARSER_SCANNER (scanner), TOKEN_EOF);
+  g_return_val_if_fail (VIVI_IS_PARSER_SCANNER (scanner), TOKEN_NONE);
 
   vivi_parser_scanner_advance (scanner);
 
@@ -319,7 +318,7 @@ vivi_parser_scanner_get_next_token (ViviParserScanner *scanner)
 ViviParserScannerToken
 vivi_parser_scanner_peek_next_token (ViviParserScanner *scanner)
 {
-  g_return_val_if_fail (VIVI_IS_PARSER_SCANNER (scanner), TOKEN_EOF);
+  g_return_val_if_fail (VIVI_IS_PARSER_SCANNER (scanner), TOKEN_NONE);
 
   return vivi_parser_scanner_get_value (scanner, 1)->token;
 }
diff --git a/vivified/code/vivi_parser_scanner.h b/vivified/code/vivi_parser_scanner.h
index 4840219..d514be6 100644
--- a/vivified/code/vivi_parser_scanner.h
+++ b/vivified/code/vivi_parser_scanner.h
@@ -30,7 +30,6 @@ G_BEGIN_DECLS
 typedef enum {
   // special
   TOKEN_NONE = 0,
-  TOKEN_EOF,
   TOKEN_ERROR,
   TOKEN_UNKNOWN,
   TOKEN_LINE_TERMINATOR,
diff --git a/vivified/code/vivi_parser_scanner_lex.l b/vivified/code/vivi_parser_scanner_lex.l
index af1e81e..85bb04d 100644
--- a/vivified/code/vivi_parser_scanner_lex.l
+++ b/vivified/code/vivi_parser_scanner_lex.l
@@ -69,7 +69,7 @@ identifier_part		[$_a-zA-Z0-9]
 			  return TOKEN_LINE_TERMINATOR;
 			}
 
-<<EOF>>			{ return TOKEN_EOF; }
+<<EOF>>			{ return TOKEN_NONE; }
 
 [ \t]			{ count (); /* skip */ }
 
commit b82aa1c75950b367cc69ce5691c3bd21ebf841f2
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Apr 25 16:16:04 2008 +0200

    rewrite ViviParserScanner
    
    we now keep a queue of values, so we can peek infinitely many tokens.
    Also reorganize the Makefile to run flex manually to get the header
    file autocreated. The current scanner doesn't work, because it messes up NONE
    and EOF tokens.

diff --git a/vivified/code/.gitignore b/vivified/code/.gitignore
index 576ea9b..980424f 100644
--- a/vivified/code/.gitignore
+++ b/vivified/code/.gitignore
@@ -12,6 +12,7 @@ Makefile.in
 *.loT
 
 vivi_parser_scanner_lex.c
+vivi_parser_scanner_lex.h
 
 vivi-decompile
 vivi-compile
diff --git a/vivified/code/Makefile.am b/vivified/code/Makefile.am
index 8a642cd..5550cc9 100644
--- a/vivified/code/Makefile.am
+++ b/vivified/code/Makefile.am
@@ -2,12 +2,22 @@ SUBDIRS = test
 
 noinst_LTLIBRARIES = libvivified-parser-lex.la libvivified-compiler.la
 
+BUILT_SOURCES = \
+	vivi_parser_scanner_lex.c \
+	vivi_parser_scanner_lex.h
+
+vivi_parser_scanner_lex.h: vivi_parser_scanner_lex.c
+	$(LEX) vivi_parser_scanner_lex.l
+
+vivi_parser_scanner_lex.c: vivi_parser_scanner_lex.l
+	$(LEX) vivi_parser_scanner_lex.l
+
 # we create own .la for lex generated code, so we can disable some warnings
 libvivified_parser_lex_la_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) -Wno-switch-default -Wno-missing-declarations -Wno-missing-prototypes -Wno-sign-compare -Wno-unused-function -Wno-missing-noreturn
 libvivified_parser_lex_la_LDFLAGS = $(SWFDEC_LIBS)
 
 libvivified_parser_lex_la_SOURCES = \
-	vivi_parser_scanner_lex.l
+	vivi_parser_scanner_lex.c
 
 libvivified_compiler_la_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS)
 libvivified_compiler_la_LDFLAGS = $(SWFDEC_LIBS)
@@ -156,7 +166,7 @@ noinst_HEADERS = \
 	vivi_decompiler.h \
 	vivi_decompiler_block.h \
 	vivi_decompiler_duplicate.h \
-	vivi_decompiler_state.h
+	vivi_decompiler_state.h \
 	vivi_decompiler_unknown.h \
 	vivi_parser.h \
 	vivi_parser_scanner.h \
diff --git a/vivified/code/vivi_parser.c b/vivified/code/vivi_parser.c
index 37c1633..bc25fd5 100644
--- a/vivified/code/vivi_parser.c
+++ b/vivified/code/vivi_parser.c
@@ -160,6 +160,7 @@ vivi_parser_error (ParseData *data, const char *format, ...)
 {
   va_list args;
   char *message;
+  const ViviParserValue *val;
 
   g_return_if_fail (data != NULL);
   g_return_if_fail (format != NULL);
@@ -168,7 +169,8 @@ vivi_parser_error (ParseData *data, const char *format, ...)
   message = g_strdup_vprintf (format, args);
   va_end (args);
 
-  g_printerr ("%i: error: %s\n", data->scanner->next_line_number, message);
+  val = vivi_parser_scanner_get_value (data->scanner, 1);
+  g_printerr ("%i: error: %s\n", val->line_number, message);
 
   g_free (message);
 
@@ -201,8 +203,8 @@ vivi_parser_error_unexpected_or (ParseData *data, ...)
 
   g_string_append (message, " before ");
 
-  g_string_append (message,
-      vivi_parser_token_name (data->scanner->next_token));
+  g_string_append (message, vivi_parser_token_name (
+	vivi_parser_scanner_peek_next_token (data->scanner)));
 
   vivi_parser_error (data, "%s", g_string_free (message, FALSE));
 }
@@ -230,22 +232,19 @@ vivi_parser_error_unexpected_line_terminator (ParseData *data, guint expected)
 G_GNUC_WARN_UNUSED_RESULT static gboolean
 peek_line_terminator (ParseData *data)
 {
-  vivi_parser_scanner_peek_next_token (data->scanner);
-  return data->scanner->next_line_terminator;
+  return vivi_parser_scanner_get_value (data->scanner, 1)->line_terminator;
 }
 
 G_GNUC_WARN_UNUSED_RESULT static gboolean
 peek_token (ParseData *data, ViviParserScannerToken token)
 {
-  vivi_parser_scanner_peek_next_token (data->scanner);
-  return (data->scanner->next_token == token);
+  return vivi_parser_scanner_peek_next_token (data->scanner) == token;
 }
 
 static void
 parse_token (ParseData *data, ViviParserScannerToken token)
 {
-  vivi_parser_scanner_peek_next_token (data->scanner);
-  if (data->scanner->next_token != token) {
+  if (vivi_parser_scanner_peek_next_token (data->scanner) != token) {
     vivi_parser_error_unexpected (data, token);
   } else {
     vivi_parser_scanner_get_next_token (data->scanner);
@@ -265,14 +264,15 @@ try_parse_token (ParseData *data, ViviParserScannerToken token)
 static void
 parse_automatic_semicolon (ParseData *data)
 {
+  ViviParserScannerToken token;
+
   if (try_parse_token (data, TOKEN_SEMICOLON))
     return;
   if (peek_line_terminator (data))
     return;
 
-  vivi_parser_scanner_peek_next_token (data->scanner);
-  if (data->scanner->next_token == TOKEN_BRACE_LEFT ||
-      data->scanner->next_token == TOKEN_EOF)
+  token = vivi_parser_scanner_peek_next_token (data->scanner);
+  if (token == TOKEN_BRACE_LEFT || token == TOKEN_EOF)
     return;
 
   vivi_parser_error_unexpected (data, TOKEN_SEMICOLON);
@@ -517,7 +517,7 @@ vivi_parser_add_label (ParseData *data, ViviCodeLabel *label)
 static gsize
 vivi_parser_get_position (ParseData *data)
 {
-  return data->scanner->position;
+  return vivi_parser_scanner_get_value (data->scanner, 0)->position;
 }
 
 static void
@@ -621,8 +621,10 @@ parse_null (ParseData *data)
 G_GNUC_UNUSED static gboolean
 peek_boolean_value (ParseData *data)
 {
-  if (data->scanner->next_value.type == VALUE_TYPE_BOOLEAN) {
-    return data->scanner->next_value.v_boolean;
+  const ViviParserValue *value = vivi_parser_scanner_get_value (data->scanner, 1);
+
+  if (value->type == VALUE_TYPE_BOOLEAN) {
+    return value->value.v_boolean;
   } else {
     return FALSE;
   }
@@ -631,10 +633,13 @@ peek_boolean_value (ParseData *data)
 static gboolean
 parse_boolean_value (ParseData *data)
 {
+  const ViviParserValue *value;
+  
   parse_token (data, TOKEN_BOOLEAN);
 
-  if (data->scanner->value.type == VALUE_TYPE_BOOLEAN) {
-    return data->scanner->value.v_boolean;
+  value = vivi_parser_scanner_get_value (data->scanner, 0);
+  if (value->type == VALUE_TYPE_BOOLEAN) {
+    return value->value.v_boolean;
   } else {
     return FALSE;
   }
@@ -663,8 +668,10 @@ parse_boolean (ParseData *data)
 G_GNUC_UNUSED static double
 peek_numeric_value (ParseData *data)
 {
-  if (data->scanner->next_value.type == VALUE_TYPE_NUMBER) {
-    return data->scanner->next_value.v_number;
+  const ViviParserValue *value = vivi_parser_scanner_get_value (data->scanner, 1);
+
+  if (value->type == VALUE_TYPE_NUMBER) {
+    return value->value.v_number;
   } else {
     return NAN;
   }
@@ -673,10 +680,13 @@ peek_numeric_value (ParseData *data)
 static double
 parse_numeric_value (ParseData *data)
 {
+  const ViviParserValue *value;
+
   parse_token (data, TOKEN_NUMBER);
 
-  if (data->scanner->value.type == VALUE_TYPE_NUMBER) {
-    return data->scanner->value.v_number;
+  value = vivi_parser_scanner_get_value (data->scanner, 0);
+  if (value->type == VALUE_TYPE_NUMBER) {
+    return value->value.v_number;
   } else {
     return NAN;
   }
@@ -705,8 +715,9 @@ parse_numeric (ParseData *data)
 G_GNUC_UNUSED static const char *
 peek_string_value (ParseData *data)
 {
-  if (data->scanner->next_value.type == VALUE_TYPE_STRING) {
-    return data->scanner->next_value.v_string;
+  const ViviParserValue *value = vivi_parser_scanner_get_value (data->scanner, 1);
+  if (value->type == VALUE_TYPE_STRING) {
+    return value->value.v_string;
   } else {
     return "undefined";
   }
@@ -715,10 +726,13 @@ peek_string_value (ParseData *data)
 static const char *
 parse_string_value (ParseData *data)
 {
+  const ViviParserValue *value;
+
   parse_token (data, TOKEN_STRING);
 
-  if (data->scanner->value.type == VALUE_TYPE_STRING) {
-    return data->scanner->value.v_string;
+  value = vivi_parser_scanner_get_value (data->scanner, 0);
+  if (value->type == VALUE_TYPE_STRING) {
+    return value->value.v_string;
   } else {
     return "undefined";
   }
@@ -792,8 +806,10 @@ parse_literal (ParseData *data)
 static const char *
 peek_identifier_value (ParseData *data)
 {
-  if (data->scanner->next_value.type == VALUE_TYPE_IDENTIFIER) {
-    return data->scanner->next_value.v_identifier;
+  const ViviParserValue *value = vivi_parser_scanner_get_value (data->scanner, 1);
+
+  if (value->type == VALUE_TYPE_IDENTIFIER) {
+    return value->value.v_identifier;
   } else {
     return "undefined";
   }
@@ -802,10 +818,12 @@ peek_identifier_value (ParseData *data)
 static const char *
 parse_identifier_value (ParseData *data)
 {
+  const ViviParserValue *value;
   parse_token (data, TOKEN_IDENTIFIER);
 
-  if (data->scanner->value.type == VALUE_TYPE_IDENTIFIER) {
-    return data->scanner->value.v_identifier;
+  value = vivi_parser_scanner_get_value (data->scanner, 0);
+  if (value->type == VALUE_TYPE_IDENTIFIER) {
+    return value->value.v_identifier;
   } else {
     return "undefined";
   }
@@ -1387,7 +1405,7 @@ peek_builtin_call (ParseData *data)
   if (!peek_token (data, TOKEN_IDENTIFIER))
     return FALSE;
 
-  identifier = data->scanner->next_value.v_identifier;
+  identifier = vivi_parser_scanner_get_value (data->scanner, 1)->value.v_identifier;
 
   // TODO: Check that ( follows?
 
@@ -1789,8 +1807,7 @@ parse_postfix_expression (ParseData *data, ViviCodeStatement **statement)
 static gboolean
 peek_unary_expression (ParseData *data)
 {
-  vivi_parser_scanner_peek_next_token (data->scanner);
-  switch ((guint)data->scanner->next_token) {
+  switch ((guint) vivi_parser_scanner_peek_next_token (data->scanner)) {
     /*case TOKEN_DELETE:
     case TOKEN_VOID:
     case TOKEN_TYPEOF:*/
@@ -1813,8 +1830,7 @@ parse_unary_expression (ParseData *data, ViviCodeStatement **statement)
 {
   ViviCodeValue *value, *tmp, *one;
 
-  vivi_parser_scanner_peek_next_token (data->scanner);
-  switch ((guint)data->scanner->next_token) {
+  switch ((guint) vivi_parser_scanner_peek_next_token (data->scanner)) {
     /*case TOKEN_DELETE:
     case TOKEN_VOID:
     case TOKEN_TYPEOF:*/
@@ -1833,7 +1849,7 @@ parse_unary_expression (ParseData *data, ViviCodeStatement **statement)
       }
 
       one = vivi_code_number_new (1);
-      tmp = (data->scanner->next_token == TOKEN_INCREASE ?
+      tmp = (vivi_parser_scanner_peek_next_token (data->scanner) == TOKEN_INCREASE ?
 	  vivi_code_add_new : vivi_code_subtract_new) (value, one);
       g_object_unref (one);
 
@@ -2205,9 +2221,7 @@ parse_assignment_expression (ParseData *data, ViviCodeStatement **statement)
     return value;
   }
 
-  vivi_parser_scanner_peek_next_token (data->scanner);
-  switch ((guint)data->scanner->next_token) {
-    case TOKEN_ASSIGN_MULTIPLY:
+  switch ((guint) vivi_parser_scanner_peek_next_token (data->scanner)) {
       func = vivi_code_multiply_new;
       break;
     case TOKEN_ASSIGN_DIVIDE:
@@ -2911,7 +2925,7 @@ parse_program (ParseData *data)
   vivi_parser_start_level (data);
 
   parse_statement_list (data, peek_source_element, parse_source_element,
-      &statement, TOKEN_NONE);
+      &statement, TOKEN_EOF);
   parse_token (data, TOKEN_EOF);
 
   vivi_parser_end_level (data);
diff --git a/vivified/code/vivi_parser_scanner.c b/vivified/code/vivi_parser_scanner.c
index 47e3b46..ef0ccc5 100644
--- a/vivified/code/vivi_parser_scanner.c
+++ b/vivified/code/vivi_parser_scanner.c
@@ -25,25 +25,20 @@
 
 #include "vivi_parser_scanner_lex.h"
 
-extern ViviParserScannerValue lex_value;
-extern guint lex_line_number;
-extern guint lex_column;
-extern gsize lex_position;
-
 G_DEFINE_TYPE (ViviParserScanner, vivi_parser_scanner, G_TYPE_OBJECT)
 
 static void
-vivi_parser_scanner_free_type_value (ViviParserScannerValue *value)
+vivi_parser_value_reset (ViviParserValue *value)
 {
   switch (value->type) {
     case VALUE_TYPE_STRING:
-      g_free (value->v_string);
+      g_free (value->value.v_string);
       break;
     case VALUE_TYPE_IDENTIFIER:
-      g_free (value->v_identifier);
+      g_free (value->value.v_identifier);
       break;
     case VALUE_TYPE_ERROR:
-      g_free (value->v_error);
+      g_free (value->value.v_error);
       break;
     case VALUE_TYPE_NONE:
     case VALUE_TYPE_BOOLEAN:
@@ -55,16 +50,29 @@ vivi_parser_scanner_free_type_value (ViviParserScannerValue *value)
       break;
   }
 
+  /* FIXME: do a memset 0 here? */
   value->type = VALUE_TYPE_NONE;
 }
 
 static void
+vivi_parser_scanner_pop (ViviParserScanner *scanner)
+{
+  ViviParserValue *value;
+
+  /* ensure there is a value */
+  vivi_parser_scanner_get_value (scanner, 0);
+  value = swfdec_ring_buffer_pop (scanner->values);
+
+  vivi_parser_value_reset (value);
+}
+
+static void
 vivi_parser_scanner_dispose (GObject *object)
 {
   ViviParserScanner *scanner = VIVI_PARSER_SCANNER (object);
 
-  vivi_parser_scanner_free_type_value (&scanner->value);
-  vivi_parser_scanner_free_type_value (&scanner->next_value);
+  while (swfdec_ring_buffer_get_n_elements (scanner->values))
+    vivi_parser_scanner_pop (scanner);
 
   G_OBJECT_CLASS (vivi_parser_scanner_parent_class)->dispose (object);
 }
@@ -78,8 +86,9 @@ vivi_parser_scanner_class_init (ViviParserScannerClass *klass)
 }
 
 static void
-vivi_parser_scanner_init (ViviParserScanner *token)
+vivi_parser_scanner_init (ViviParserScanner *scanner)
 {
+  scanner->values = swfdec_ring_buffer_new_for_type (ViviParserValue, 4);
 }
 
 static const struct {
@@ -223,52 +232,55 @@ const char *vivi_parser_scanner_token_name (ViviParserScannerToken token)
 static void
 vivi_parser_scanner_advance (ViviParserScanner *scanner)
 {
-  g_return_if_fail (VIVI_IS_PARSER_SCANNER (scanner));
-
-  vivi_parser_scanner_free_type_value (&scanner->value);
+  ViviParserValue *value;
 
-  scanner->token = scanner->next_token;
-  scanner->value = scanner->next_value;
-  scanner->line_terminator = scanner->next_line_terminator;
-  scanner->line_number = scanner->next_line_number;
-  scanner->column = scanner->next_column;
-  scanner->position = scanner->next_position;
+  g_return_if_fail (VIVI_IS_PARSER_SCANNER (scanner));
 
-  while (scanner->waiting_errors != NULL) {
-    if (scanner->error_handler != NULL) {
-      scanner->error_handler (scanner->waiting_errors->data,
-	  scanner->error_handler_data);
-      g_free (scanner->waiting_errors->data);
-    }
-    scanner->waiting_errors = g_slist_delete_link (scanner->waiting_errors,
-	scanner->waiting_errors);
+  value = swfdec_ring_buffer_push (scanner->values);
+  if (value == NULL) {
+    swfdec_ring_buffer_set_size (scanner->values,
+	swfdec_ring_buffer_get_size (scanner->values) + 4);
+    value = swfdec_ring_buffer_push (scanner->values);
   }
 
   if (scanner->file == NULL) {
-    scanner->next_token = TOKEN_EOF;
-    scanner->next_value.v_string = NULL;
+    value->token = TOKEN_EOF;
+    value->type = VALUE_TYPE_NONE;
+    value->column = 0;
+    value->position = 0;
+    value->line_number = 0;
+    value->line_terminator = FALSE;
   } else {
-    scanner->next_line_terminator = FALSE;
-    do {
-      scanner->next_token = yylex ();
-      if (scanner->next_token == TOKEN_LINE_TERMINATOR) {
-	scanner->next_line_terminator = TRUE;
-	vivi_parser_scanner_free_type_value (&lex_value);
-      } else if (scanner->next_token == TOKEN_ERROR) {
-	scanner->waiting_errors = g_slist_prepend (scanner->waiting_errors,
-	    lex_value.v_error);
-	lex_value.type = VALUE_TYPE_NONE;
+    value->line_terminator = FALSE;
+    for (;;) {
+      value->token = yylex (value);
+      value->type = VALUE_TYPE_NONE;
+      g_print ("got %s\n", vivi_parser_scanner_token_name (value->token));
+      if (value->token == TOKEN_LINE_TERMINATOR) {
+	value->line_terminator = TRUE;
+	vivi_parser_value_reset (value);
+      } else if (value->token == TOKEN_ERROR) {
+	vivi_parser_scanner_error (scanner, 0, 0, "%s", value->value.v_error);
+	vivi_parser_value_reset (value);
+      } else {
+	break;
       }
-    } while (scanner->next_token == TOKEN_LINE_TERMINATOR ||
-	scanner->next_token == TOKEN_ERROR);
+    }
+    value->line_number = yylineno;
+    value->column = 0; /* FIXME */
+    value->position = 0; /* FIXME */
+  }
+}
 
-    scanner->next_value = lex_value;
-    scanner->next_line_number = lex_line_number;
-    scanner->next_column = lex_column;
-    scanner->next_position = lex_position;
+const ViviParserValue *
+vivi_parser_scanner_get_value (ViviParserScanner *scanner, guint i)
+{
+  g_return_val_if_fail (VIVI_IS_PARSER_SCANNER (scanner), NULL);
 
-    lex_value.type = VALUE_TYPE_NONE;
+  while (swfdec_ring_buffer_get_n_elements (scanner->values) <= i) {
+    vivi_parser_scanner_advance (scanner);
   }
+  return swfdec_ring_buffer_peek_nth (scanner->values, i);
 }
 
 ViviParserScanner *
@@ -280,14 +292,9 @@ vivi_parser_scanner_new (FILE *file)
 
   scanner = g_object_new (VIVI_TYPE_PARSER_SCANNER, NULL);
   scanner->file = file;
-  scanner->line_number = scanner->next_line_number = lex_line_number = 1;
-  scanner->column = scanner->next_column = lex_column = 0;
-  scanner->position = scanner->next_position = lex_position = 0;
 
   yyrestart (file);
 
-  vivi_parser_scanner_advance (scanner);
-
   return scanner;
 }
 
@@ -306,7 +313,7 @@ vivi_parser_scanner_get_next_token (ViviParserScanner *scanner)
 
   vivi_parser_scanner_advance (scanner);
 
-  return scanner->token;
+  return vivi_parser_scanner_get_value (scanner, 0)->token;
 }
 
 ViviParserScannerToken
@@ -314,33 +321,41 @@ vivi_parser_scanner_peek_next_token (ViviParserScanner *scanner)
 {
   g_return_val_if_fail (VIVI_IS_PARSER_SCANNER (scanner), TOKEN_EOF);
 
-  return scanner->next_token;
+  return vivi_parser_scanner_get_value (scanner, 1)->token;
 }
 
-guint
-vivi_parser_scanner_cur_line (ViviParserScanner *scanner)
+void
+vivi_parser_scanner_error (ViviParserScanner *scanner, 
+    guint line, int column, const char *format, ...)
 {
-  g_return_val_if_fail (VIVI_IS_PARSER_SCANNER (scanner), 0);
+  va_list args;
 
-  return scanner->line_number;
+  g_return_if_fail (VIVI_IS_PARSER_SCANNER (scanner));
+  g_return_if_fail (column >= -1);
+  g_return_if_fail (format != NULL);
+
+  va_start (args, format);
+  vivi_parser_scanner_errorv (scanner, line, column, format, args);
+  va_end (args);
 }
 
-guint
-vivi_parser_scanner_cur_column (ViviParserScanner *scanner)
+void
+vivi_parser_scanner_errorv (ViviParserScanner *scanner, 
+    guint line, int column, const char *format, va_list args)
 {
-  g_return_val_if_fail (VIVI_IS_PARSER_SCANNER (scanner), 0);
+  char *message;
 
-  // TODO
-
-  return 0;
-}
+  g_return_if_fail (VIVI_IS_PARSER_SCANNER (scanner));
+  g_return_if_fail (column >= -1);
+  g_return_if_fail (format != NULL);
 
-char *
-vivi_parser_scanner_get_line (ViviParserScanner *scanner)
-{
-  g_return_val_if_fail (VIVI_IS_PARSER_SCANNER (scanner), 0);
+  message = g_strdup_vprintf (format, args);
 
-  // TODO
+  if (column >= 0) {
+    g_printerr ("%u,%i: error: %s\n", line, column, message);
+  } else {
+    g_printerr ("%u: error: %s\n", line, message);
+  }
 
-  return g_strdup ("");
+  g_free (message);
 }
diff --git a/vivified/code/vivi_parser_scanner.h b/vivified/code/vivi_parser_scanner.h
index 073bfa9..4840219 100644
--- a/vivified/code/vivi_parser_scanner.h
+++ b/vivified/code/vivi_parser_scanner.h
@@ -22,6 +22,7 @@
 
 #include <stdio.h>
 #include <swfdec/swfdec.h>
+#include <swfdec/swfdec_ringbuffer.h>
 
 G_BEGIN_DECLS
 
@@ -157,15 +158,20 @@ typedef enum {
 } ViviParserScannerValueType;
 
 typedef struct {
+  ViviParserScannerToken	token;
   ViviParserScannerValueType	type;
   union {
-    gboolean	v_boolean;
-    double	v_number;
-    char *	v_string;
-    char *	v_identifier;
-    char *	v_error;
-  };
-} ViviParserScannerValue;
+    gboolean	  		v_boolean;
+    double	  		v_number;
+    char *			v_string;
+    char *			v_identifier;
+    char *			v_error;
+  }				value;
+  gboolean			line_terminator;
+  guint				line_number;
+  guint				column;
+  gsize				position;
+} ViviParserValue;
 
 typedef void (*ViviParserScannerFunction) (const char *text, gpointer user_data);
 
@@ -187,27 +193,8 @@ struct _ViviParserScanner
 
   ViviParserScannerFunction	error_handler;
   gpointer			error_handler_data;
-  GSList *			waiting_errors;
-
-  ViviParserScannerToken	token;
-  ViviParserScannerToken	next_token;
-
-  ViviParserScannerValue	value;
-  ViviParserScannerValue	next_value;
-
-  gboolean			line_terminator;
-  gboolean			next_line_terminator;
 
-  guint				line_number;
-  guint				next_line_number;
-
-  guint				column;
-  guint				next_column;
-
-  gsize				position;
-  gsize				next_position;
-
-  ViviParserScannerToken	expected;
+  SwfdecRingBuffer *		values;
 };
 
 struct _ViviParserScannerClass
@@ -222,14 +209,24 @@ void				vivi_parser_scanner_set_error_handler (ViviParserScanner *	scanner,
 								 ViviParserScannerFunction	error_handler,
 								 gpointer			user_data);
 
-ViviParserScannerToken	vivi_parser_scanner_get_next_token	(ViviParserScanner *	scanner);
-ViviParserScannerToken	vivi_parser_scanner_peek_next_token	(ViviParserScanner *	scanner);
+ViviParserScannerToken		vivi_parser_scanner_get_next_token	(ViviParserScanner *	scanner);
+ViviParserScannerToken		vivi_parser_scanner_peek_next_token	(ViviParserScanner *	scanner);
 
-const char *			vivi_parser_scanner_token_name	(ViviParserScannerToken token);
-guint				vivi_parser_scanner_cur_line	(ViviParserScanner *scanner);
-guint				vivi_parser_scanner_cur_column	(ViviParserScanner *scanner);
-char *				vivi_parser_scanner_get_line	(ViviParserScanner *scanner);
+const ViviParserValue *		vivi_parser_scanner_get_value 	(ViviParserScanner *	scanner,
+								 guint			i);
 
+void				vivi_parser_scanner_error	(ViviParserScanner *	scanner, 
+								 guint			line,
+								 int			column,
+								 const char *		format,
+								 ...) G_GNUC_PRINTF (4, 5);
+void				vivi_parser_scanner_errorv	(ViviParserScanner *	scanner, 
+								 guint			line,
+								 int			column,
+								 const char *		format,
+								 va_list		args);
+
+const char *			vivi_parser_scanner_token_name	(ViviParserScannerToken token);
 
 G_END_DECLS
 #endif
diff --git a/vivified/code/vivi_parser_scanner_lex.h b/vivified/code/vivi_parser_scanner_lex.h
deleted file mode 100644
index ff2a155..0000000
--- a/vivified/code/vivi_parser_scanner_lex.h
+++ /dev/null
@@ -1,315 +0,0 @@
-/* Vivified
- * Copyright (C) 2008 Pekka Lampila <pekka.lampila at iki.fi>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
- * Boston, MA  02110-1301  USA
- */
-
-#ifndef yyHEADER_H
-#define yyHEADER_H 1
-#define yyIN_HEADER 1
-
-#line 6 "vivi_parser_scanner_lex.h"
-
-#line 8 "vivi_parser_scanner_lex.h"
-
-#define  YY_INT_ALIGNED short int
-
-/* A lexical scanner generated by flex */
-
-#define FLEX_SCANNER
-#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 34
-#if YY_FLEX_SUBMINOR_VERSION > 0
-#define FLEX_BETA
-#endif
-
-/* First, we deal with  platform-specific or compiler-specific issues. */
-
-/* begin standard C headers. */
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/* end standard C headers. */
-
-/* flex integer type definitions */
-
-#ifndef FLEXINT_H
-#define FLEXINT_H
-
-/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
-
-#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-
-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
- * if you want the limit (max/min) macros for int types. 
- */
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS 1
-#endif
-
-#include <inttypes.h>
-typedef int8_t flex_int8_t;
-typedef uint8_t flex_uint8_t;
-typedef int16_t flex_int16_t;
-typedef uint16_t flex_uint16_t;
-typedef int32_t flex_int32_t;
-typedef uint32_t flex_uint32_t;
-#else
-typedef signed char flex_int8_t;
-typedef short int flex_int16_t;
-typedef int flex_int32_t;
-typedef unsigned char flex_uint8_t; 
-typedef unsigned short int flex_uint16_t;
-typedef unsigned int flex_uint32_t;
-#endif /* ! C99 */
-
-/* Limits of integral types. */
-#ifndef INT8_MIN
-#define INT8_MIN               (-128)
-#endif
-#ifndef INT16_MIN
-#define INT16_MIN              (-32767-1)
-#endif
-#ifndef INT32_MIN
-#define INT32_MIN              (-2147483647-1)
-#endif
-#ifndef INT8_MAX
-#define INT8_MAX               (127)
-#endif
-#ifndef INT16_MAX
-#define INT16_MAX              (32767)
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX              (2147483647)
-#endif
-#ifndef UINT8_MAX
-#define UINT8_MAX              (255U)
-#endif
-#ifndef UINT16_MAX
-#define UINT16_MAX             (65535U)
-#endif
-#ifndef UINT32_MAX
-#define UINT32_MAX             (4294967295U)
-#endif
-
-#endif /* ! FLEXINT_H */
-
-#ifdef __cplusplus
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else	/* ! __cplusplus */
-
-/* C99 requires __STDC__ to be defined as 1. */
-#if defined (__STDC__)
-
-#define YY_USE_CONST
-
-#endif	/* defined (__STDC__) */
-#endif	/* ! __cplusplus */
-
-#ifdef YY_USE_CONST
-#define yyconst const
-#else
-#define yyconst
-#endif
-
-/* Size of default input buffer. */
-#ifndef YY_BUF_SIZE
-#define YY_BUF_SIZE 16384
-#endif
-
-#ifndef YY_TYPEDEF_YY_BUFFER_STATE
-#define YY_TYPEDEF_YY_BUFFER_STATE
-typedef struct yy_buffer_state *YY_BUFFER_STATE;
-#endif
-
-extern int yyleng;
-
-extern FILE *yyin, *yyout;
-
-/* The following is because we cannot portably get our hands on size_t
- * (without autoconf's help, which isn't available because we want
- * flex-generated scanners to compile on their own).
- * Given that the standard has decreed that size_t exists since 1989,
- * I guess we can afford to depend on it. Manoj.
- */
-
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
-#ifndef YY_STRUCT_YY_BUFFER_STATE
-#define YY_STRUCT_YY_BUFFER_STATE
-struct yy_buffer_state
-	{
-	FILE *yy_input_file;
-
-	char *yy_ch_buf;		/* input buffer */
-	char *yy_buf_pos;		/* current position in input buffer */
-
-	/* Size of input buffer in bytes, not including room for EOB
-	 * characters.
-	 */
-	yy_size_t yy_buf_size;
-
-	/* Number of characters read into yy_ch_buf, not including EOB
-	 * characters.
-	 */
-	int yy_n_chars;
-
-	/* Whether we "own" the buffer - i.e., we know we created it,
-	 * and can realloc() it to grow it, and should free() it to
-	 * delete it.
-	 */
-	int yy_is_our_buffer;
-
-	/* Whether this is an "interactive" input source; if so, and
-	 * if we're using stdio for input, then we want to use getc()
-	 * instead of fread(), to make sure we stop fetching input after
-	 * each newline.
-	 */
-	int yy_is_interactive;
-
-	/* Whether we're considered to be at the beginning of a line.
-	 * If so, '^' rules will be active on the next match, otherwise
-	 * not.
-	 */
-	int yy_at_bol;
-
-    int yy_bs_lineno; /**< The line count. */
-    int yy_bs_column; /**< The column count. */
-    
-	/* Whether to try to fill the input buffer when we reach the
-	 * end of it.
-	 */
-	int yy_fill_buffer;
-
-	int yy_buffer_status;
-
-	};
-#endif /* !YY_STRUCT_YY_BUFFER_STATE */
-
-void yyrestart (FILE *input_file  );
-void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer  );
-YY_BUFFER_STATE yy_create_buffer (FILE *file,int size  );
-void yy_delete_buffer (YY_BUFFER_STATE b  );
-void yy_flush_buffer (YY_BUFFER_STATE b  );
-void yypush_buffer_state (YY_BUFFER_STATE new_buffer  );
-void yypop_buffer_state (void );
-
-YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size  );
-YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str  );
-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len  );
-
-void *yyalloc (yy_size_t  );
-void *yyrealloc (void *,yy_size_t  );
-void yyfree (void *  );
-
-/* Begin user sect3 */
-
-extern int yylineno;
-
-extern char *yytext;
-#define yytext_ptr yytext
-
-#ifdef YY_HEADER_EXPORT_START_CONDITIONS
-#define INITIAL 0
-
-#endif
-
-#ifndef YY_NO_UNISTD_H
-/* Special case for "unistd.h", since it is non-ANSI. We include it way
- * down here because we want the user's section 1 to have been scanned first.
- * The user has a chance to override it with an option.
- */
-#include <unistd.h>
-#endif
-
-#ifndef YY_EXTRA_TYPE
-#define YY_EXTRA_TYPE void *
-#endif
-
-/* Macros after this point can all be overridden by user definitions in
- * section 1.
- */
-
-#ifndef YY_SKIP_YYWRAP
-#ifdef __cplusplus
-extern "C" int yywrap (void );
-#else
-extern int yywrap (void );
-#endif
-#endif
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int );
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * );
-#endif
-
-#ifndef YY_NO_INPUT
-
-#endif
-
-/* Amount of stuff to slurp up with each read. */
-#ifndef YY_READ_BUF_SIZE
-#define YY_READ_BUF_SIZE 8192
-#endif
-
-/* Number of entries by which start-condition stack grows. */
-#ifndef YY_START_STACK_INCR
-#define YY_START_STACK_INCR 25
-#endif
-
-/* Default declaration of generated scanner - a define so the user can
- * easily add parameters.
- */
-#ifndef YY_DECL
-#define YY_DECL_IS_OURS 1
-
-extern int yylex (void);
-
-#define YY_DECL int yylex (void)
-#endif /* !YY_DECL */
-
-/* yy_get_previous_state - get the state just before the EOB char was reached */
-
-#undef YY_NEW_FILE
-#undef YY_FLUSH_BUFFER
-#undef yy_set_bol
-#undef yy_new_buffer
-#undef yy_set_interactive
-#undef YY_DO_BEFORE_ACTION
-
-#ifdef YY_DECL_IS_OURS
-#undef YY_DECL_IS_OURS
-#undef YY_DECL
-#endif
-
-#line 148 "vivi_parser_scanner_lex.l"
-
-
-#line 295 "vivi_parser_scanner_lex.h"
-#undef yyIN_HEADER
-#endif /* yyHEADER_H */
diff --git a/vivified/code/vivi_parser_scanner_lex.l b/vivified/code/vivi_parser_scanner_lex.l
index 8f6c696..af1e81e 100644
--- a/vivified/code/vivi_parser_scanner_lex.l
+++ b/vivified/code/vivi_parser_scanner_lex.l
@@ -1,4 +1,4 @@
-%{
+%top{
 /* Vivified
  * Copyright (C) 2008 Pekka Lampila <pekka.lampila at iki.fi>
  *
@@ -20,9 +20,12 @@
 
 #include "vivi_parser_scanner.h"
 
-ViviParserScannerValue lex_value;
+#define YY_DECL int yylex (ViviParserValue *value)
+extern YY_DECL;
+}
+
+%{
 guint lex_line_number = 0;
-guint lex_column = 0;
 gsize lex_position = 0;
 
 static void new_line (void);
@@ -34,6 +37,8 @@ static GString *string = NULL;
 %option			noyywrap
 %option			nostdinit
 %option			never-interactive
+%option			outfile="vivi_parser_scanner_lex.c"
+%option			header-file="vivi_parser_scanner_lex.h"
 
 identifier_start	[$_a-zA-Z]
 identifier_part		[$_a-zA-Z0-9]
@@ -51,8 +56,8 @@ identifier_part		[$_a-zA-Z0-9]
   <<EOF>>		{
 			  count ();
 			  BEGIN(INITIAL);
-			  lex_value.type = VALUE_TYPE_ERROR;
-			  lex_value.v_error =
+			  value->type = VALUE_TYPE_ERROR;
+			  value->value.v_error =
 			    g_strdup ("Unterminated comment");
 			  return TOKEN_ERROR;
 			}
@@ -201,36 +206,36 @@ identifier_part		[$_a-zA-Z0-9]
 "null"			{ count (); return TOKEN_NULL; }
 "true"			{
 			  count ();
-			  lex_value.type = VALUE_TYPE_BOOLEAN;
-			  lex_value.v_boolean = 1;
+			  value->type = VALUE_TYPE_BOOLEAN;
+			  value->value.v_boolean = 1;
 			  return TOKEN_BOOLEAN;
 			}
 "false"			{
 			  count ();
-			  lex_value.type = VALUE_TYPE_BOOLEAN;
-			  lex_value.v_boolean = 0;
+			  value->type = VALUE_TYPE_BOOLEAN;
+			  value->value.v_boolean = 0;
 			  return TOKEN_BOOLEAN;
 			}
 
 0[xX][0-9a-fA-F]+	{
 			  count ();
-			  lex_value.type = VALUE_TYPE_NUMBER;
-			  lex_value.v_number =
+			  value->type = VALUE_TYPE_NUMBER;
+			  value->value.v_number =
 			    g_ascii_strtoull (yytext, NULL, 16);
 			  return TOKEN_NUMBER;
 			}
 
 ([1-9][0-9]*|0)(\.[0-9]*)?([eE][+-]?[0-9]+)? {
 			  count ();
-			  lex_value.type = VALUE_TYPE_NUMBER;
-			  lex_value.v_number = g_ascii_strtod (yytext, NULL);
+			  value->type = VALUE_TYPE_NUMBER;
+			  value->value.v_number = g_ascii_strtod (yytext, NULL);
 			  return TOKEN_NUMBER;
 			}
 
 \.[0-9]+([eE][+-]?[0-9]+)? {
 			  count ();
-			  lex_value.type = VALUE_TYPE_NUMBER;
-			  lex_value.v_number = g_ascii_strtod (yytext, NULL);
+			  value->type = VALUE_TYPE_NUMBER;
+			  value->value.v_number = g_ascii_strtod (yytext, NULL);
 			  return TOKEN_NUMBER;
 			}
 
@@ -244,16 +249,16 @@ identifier_part		[$_a-zA-Z0-9]
   \"			{
 			  count ();
 			  BEGIN(INITIAL);
-			  lex_value.type = VALUE_TYPE_STRING;
-			  lex_value.v_string = g_string_free (string, FALSE);
+			  value->type = VALUE_TYPE_STRING;
+			  value->value.v_string = g_string_free (string, FALSE);
 			  return TOKEN_STRING;
 			}
   \n			{
 			  count ();
 			  BEGIN(INITIAL);
 			  g_string_free (string, TRUE);
-			  lex_value.type = VALUE_TYPE_ERROR;
-			  lex_value.v_error = g_strdup (
+			  value->type = VALUE_TYPE_ERROR;
+			  value->value.v_error = g_strdup (
 			      "Unterminated string constant");
 			  return TOKEN_ERROR;
 			}
@@ -262,8 +267,8 @@ identifier_part		[$_a-zA-Z0-9]
 			  count ();
 			  result = g_ascii_strtoull (yytext + 1, NULL, 8);
 			  if (result > 0xff || result == 0) {
-			    lex_value.type = VALUE_TYPE_ERROR;
-			    lex_value.v_error = g_strdup_printf (
+			    value->type = VALUE_TYPE_ERROR;
+			    value->value.v_error = g_strdup_printf (
 				"Invalid escape sequence %s", yytext);
 			    return TOKEN_ERROR;
 			  } else {
@@ -272,8 +277,8 @@ identifier_part		[$_a-zA-Z0-9]
 			}
   \\[0-9]+		{
 			  count ();
-			  lex_value.type = VALUE_TYPE_ERROR;
-			  lex_value.v_error = g_strdup_printf (
+			  value->type = VALUE_TYPE_ERROR;
+			  value->value.v_error = g_strdup_printf (
 			      "Invalid escape sequence %s", yytext);
 			  return TOKEN_ERROR;
 			}
@@ -282,8 +287,8 @@ identifier_part		[$_a-zA-Z0-9]
 			  count ();
 			  result = g_ascii_strtoull (yytext + 2, NULL, 16);
 			  if (result == 0) {
-			    lex_value.type = VALUE_TYPE_ERROR;
-			    lex_value.v_error = g_strdup_printf (
+			    value->type = VALUE_TYPE_ERROR;
+			    value->value.v_error = g_strdup_printf (
 				"Invalid escape sequence %s", yytext);
 			    return TOKEN_ERROR;
 			  } else {
@@ -308,15 +313,15 @@ identifier_part		[$_a-zA-Z0-9]
 
 {identifier_start}({identifier_part})* {
 			  count ();
-			  lex_value.type = VALUE_TYPE_IDENTIFIER;
-			  lex_value.v_identifier = g_strdup (yytext);
+			  value->type = VALUE_TYPE_IDENTIFIER;
+			  value->value.v_identifier = g_strdup (yytext);
 			  return TOKEN_IDENTIFIER;
 			}
 
 .			{
 			  count ();
-			  lex_value.type = VALUE_TYPE_ERROR;
-			  lex_value.v_error = g_strdup_printf (
+			  value->type = VALUE_TYPE_ERROR;
+			  value->value.v_error = g_strdup_printf (
 			      "Unknown character '%c'", yytext[0]);
 			  return TOKEN_ERROR;
 			}


More information about the Swfdec-commits mailing list