You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by ma...@apache.org on 2011/10/26 01:45:14 UTC

[lucy-commits] svn commit: r1188972 - in /incubator/lucy/branches/clownfish_lemon/clownfish/src: CFCLexHeader.l CFCParseHeader.y CFCParser.c CFCParser.h

Author: marvin
Date: Tue Oct 25 23:45:14 2011
New Revision: 1188972

URL: http://svn.apache.org/viewvc?rev=1188972&view=rev
Log:
Use memory pool instead of malloc/free in parser.

Use a memory pool for allocating all C strings inside both the Flex-based
scanner and the Lemon-based parser, deallocating them en masse by destroying
the memory pool once the parse operation completes..  This is a natural use
for a memory pool because each parse() invocation is a substantial
undertaking, yet also contained and monolithic.  The primary benefit is code
simplification (because we no longer have to worry about freeing C strings
inside the lemon grammar).  The secondary benefit is that it is harder to leak
memory, especially when a parse operation fails.

Modified:
    incubator/lucy/branches/clownfish_lemon/clownfish/src/CFCLexHeader.l
    incubator/lucy/branches/clownfish_lemon/clownfish/src/CFCParseHeader.y
    incubator/lucy/branches/clownfish_lemon/clownfish/src/CFCParser.c
    incubator/lucy/branches/clownfish_lemon/clownfish/src/CFCParser.h

Modified: incubator/lucy/branches/clownfish_lemon/clownfish/src/CFCLexHeader.l
URL: http://svn.apache.org/viewvc/incubator/lucy/branches/clownfish_lemon/clownfish/src/CFCLexHeader.l?rev=1188972&r1=1188971&r2=1188972&view=diff
==============================================================================
--- incubator/lucy/branches/clownfish_lemon/clownfish/src/CFCLexHeader.l (original)
+++ incubator/lucy/branches/clownfish_lemon/clownfish/src/CFCLexHeader.l Tue Oct 25 23:45:14 2011
@@ -29,7 +29,8 @@
     /* Dupe yytext and invoke parser. */
     #define SAVE_AND_PARSE(token_type) \
         CFCParseHeader(CFCParser_current_parser, token_type, \
-			CFCUtil_strdup(yytext), CFCParser_current_state)
+			CFCParser_dupe(CFCParser_current_state, yytext), \
+			CFCParser_current_state)
 %}
 
 CLASS_NAME_COMPONENT    [A-Z]+[A-Z0-9]*[a-z]+[A-Za-z0-9]*

Modified: incubator/lucy/branches/clownfish_lemon/clownfish/src/CFCParseHeader.y
URL: http://svn.apache.org/viewvc/incubator/lucy/branches/clownfish_lemon/clownfish/src/CFCParseHeader.y?rev=1188972&r1=1188971&r2=1188972&view=diff
==============================================================================
--- incubator/lucy/branches/clownfish_lemon/clownfish/src/CFCParseHeader.y (original)
+++ incubator/lucy/branches/clownfish_lemon/clownfish/src/CFCParseHeader.y Tue Oct 25 23:45:14 2011
@@ -17,7 +17,6 @@
  */
 
 %token_type {char*}
-%token_destructor { FREEMEM($$); }
 %token_prefix CFC_TOKENTYPE_
 
 %extra_argument { CFCParser *state }
@@ -69,11 +68,6 @@ S_start_class(CFCParser *state, CFCDocuC
                                       class_name, class_cnick, NULL,
                                       docucomment, source_class, inheritance,
                                       is_final, is_inert);
-    FREEMEM(exposure);
-    FREEMEM(declaration_modifier_list);
-    FREEMEM(class_name);
-    FREEMEM(class_cnick);
-    FREEMEM(inheritance);
     CFCBase_decref((CFCBase*)docucomment);
     return klass;
 }
@@ -94,9 +88,6 @@ S_new_var(CFCParser *state, char *exposu
                                        name, type, inert);
 
     /* Consume tokens. */
-    FREEMEM(exposure);
-    FREEMEM(modifiers);
-    FREEMEM(name);
     CFCBase_decref((CFCBase*)type);
 
     return var;
@@ -139,9 +130,6 @@ S_new_sub(CFCParser *state, CFCDocuComme
     CFCBase_decref((CFCBase*)docucomment);
     CFCBase_decref((CFCBase*)type);
     CFCBase_decref((CFCBase*)param_list);
-    FREEMEM(exposure);
-    FREEMEM(declaration_modifier_list);
-    FREEMEM(name);
 
     return sub;
 }
@@ -223,11 +211,6 @@ S_new_type(CFCParser *state, int flags, 
         type = composite;
     }
 
-    /* Consume tokens. */
-    FREEMEM(type_name);
-    FREEMEM(asterisk_postfix);
-    FREEMEM(array_postfix);
-
     return type;
 }
 
@@ -358,8 +341,6 @@ parcel_definition(A) ::= exposure_specif
          CFCUtil_die("A syntax error was detected when parsing '%s'", B);
     }
     A = CFCParcel_singleton(C, NULL);
-    FREEMEM(B);
-    FREEMEM(C);
     CFCBase_incref((CFCBase*)A);
     CFCParser_set_parcel(A);
 }
@@ -370,8 +351,6 @@ parcel_definition(A) ::= exposure_specif
          CFCUtil_die("A syntax error was detected when parsing '%s'", B);
     }
     A = CFCParcel_singleton(C, D);
-    FREEMEM(C);
-    FREEMEM(D);
     CFCBase_incref((CFCBase*)A);
     CFCParser_set_parcel(A);
 }
@@ -420,7 +399,6 @@ class_head(A) ::= class_head(B) COLON id
 {
     A = B;
     CFCClass_add_attribute(A, C, "1");
-    FREEMEM(C);
 }
 
 class_defs(A) ::= class_head(B) LEFT_CURLY_BRACE.
@@ -453,7 +431,7 @@ class_defs(A) ::= class_defs(B) subrouti
 var_declaration_statement(A) ::= 
     type(D) declarator(E) SEMICOLON.
 {
-    A = S_new_var(state, CFCUtil_strdup("parcel"), NULL, D, E);
+    A = S_new_var(state, CFCParser_dupe(state, "parcel"), NULL, D, E);
 }
 var_declaration_statement(A) ::= 
     exposure_specifier(B)
@@ -465,7 +443,7 @@ var_declaration_statement(A) ::= 
     declaration_modifier_list(C)
     type(D) declarator(E) SEMICOLON.
 {
-    A = S_new_var(state, CFCUtil_strdup("parcel"), C, D, E);
+    A = S_new_var(state, CFCParser_dupe(state, "parcel"), C, D, E);
 }
 var_declaration_statement(A) ::= 
     exposure_specifier(B)
@@ -572,16 +550,16 @@ integer_type_specifier(A) ::= BOOL_T.   
 float_type_specifier(A) ::= FLOAT.   { A = KW_FLOAT; }
 float_type_specifier(A) ::= DOUBLE.  { A = KW_DOUBLE; }
 
-type_name(A) ::= void_type_specifier(B).     { A = CFCUtil_strdup(B); }
-type_name(A) ::= va_list_specifier(B).       { A = CFCUtil_strdup(B); }
-type_name(A) ::= integer_type_specifier(B).  { A = CFCUtil_strdup(B); }
-type_name(A) ::= float_type_specifier(B).    { A = CFCUtil_strdup(B); }
+type_name(A) ::= void_type_specifier(B).     { A = CFCParser_dupe(state, B); }
+type_name(A) ::= va_list_specifier(B).       { A = CFCParser_dupe(state, B); }
+type_name(A) ::= integer_type_specifier(B).  { A = CFCParser_dupe(state, B); }
+type_name(A) ::= float_type_specifier(B).    { A = CFCParser_dupe(state, B); }
 type_name(A) ::= identifier(B).              { A = B; }
 
-exposure_specifier(A) ::= PUBLIC.  { A = CFCUtil_strdup("public"); }
-exposure_specifier(A) ::= PRIVATE. { A = CFCUtil_strdup("private"); }
-exposure_specifier(A) ::= PARCEL.  { A = CFCUtil_strdup("parcel"); }
-exposure_specifier(A) ::= LOCAL.   { A = CFCUtil_strdup("local"); }
+exposure_specifier(A) ::= PUBLIC.  { A = CFCParser_dupe(state, "public"); }
+exposure_specifier(A) ::= PRIVATE. { A = CFCParser_dupe(state, "private"); }
+exposure_specifier(A) ::= PARCEL.  { A = CFCParser_dupe(state, "parcel"); }
+exposure_specifier(A) ::= LOCAL.   { A = CFCParser_dupe(state, "local"); }
 
 type_qualifier(A) ::= CONST.       { A = CFCTYPE_CONST; }
 type_qualifier(A) ::= NULLABLE.    { A = CFCTYPE_NULLABLE; }
@@ -598,10 +576,10 @@ type_qualifier_list(A) ::= type_qualifie
     A |= C;
 }
 
-declaration_modifier(A) ::= INERT.      { A = CFCUtil_strdup("inert"); }
-declaration_modifier(A) ::= INLINE.     { A = CFCUtil_strdup("inline"); }
-declaration_modifier(A) ::= ABSTRACT.   { A = CFCUtil_strdup("abstract"); }
-declaration_modifier(A) ::= FINAL.      { A = CFCUtil_strdup("final"); }
+declaration_modifier(A) ::= INERT.      { A = CFCParser_dupe(state, "inert"); }
+declaration_modifier(A) ::= INLINE.     { A = CFCParser_dupe(state, "inline"); }
+declaration_modifier(A) ::= ABSTRACT.   { A = CFCParser_dupe(state, "abstract"); }
+declaration_modifier(A) ::= FINAL.      { A = CFCParser_dupe(state, "final"); }
 
 declaration_modifier_list(A) ::= declaration_modifier(B).
 {
@@ -609,27 +587,31 @@ declaration_modifier_list(A) ::= declara
 }
 declaration_modifier_list(A) ::= declaration_modifier_list(B) declaration_modifier(C).
 {
-    A = CFCUtil_cat(B, " ", C, NULL);
-    FREEMEM(C);
+    size_t size = strlen(B) + strlen(C) + 2;
+    A = (char*)CFCParser_allocate(state, size);
+    sprintf(A, "%s %s", B, C);
 }
 
 asterisk_postfix(A) ::= ASTERISK.
 {
-    A = CFCUtil_strdup("*");
+    A = CFCParser_dupe(state, "*");
 }
 asterisk_postfix(A) ::= asterisk_postfix(B) ASTERISK.
 {
-    A = CFCUtil_cat(B, "*", NULL);
+    size_t size = strlen(B) + 2;
+    A = (char*)CFCParser_allocate(state, size);
+    sprintf(A, "%s*", B);
 }
 
 array_postfix_elem(A) ::= LEFT_SQUARE_BRACKET RIGHT_SQUARE_BRACKET.
 {
-    A = CFCUtil_strdup("[]");
+    A = CFCParser_dupe(state, "[]");
 }
 array_postfix_elem(A) ::= LEFT_SQUARE_BRACKET integer_literal(B) RIGHT_SQUARE_BRACKET.
 {
-    A = CFCUtil_cat(CFCUtil_strdup(""), "[", B, "]", NULL);
-    FREEMEM(B);
+    size_t size = strlen(B) + 3;
+    A = (char*)CFCParser_allocate(state, size);
+    sprintf(A, "[%s]", B);
 }
 
 array_postfix(A) ::= array_postfix_elem(B). 
@@ -638,17 +620,18 @@ array_postfix(A) ::= array_postfix_elem(
 }
 array_postfix(A) ::= array_postfix(B) array_postfix_elem(C).
 {
-    A = CFCUtil_cat(B, C, NULL);
-    FREEMEM(C);
+    size_t size = strlen(B) + strlen(C) + 1;
+    A = (char*)CFCParser_allocate(state, size);
+    sprintf(A, "%s%s", B, C);
 }
 
 scalar_constant(A) ::= hex_literal(B).     { A = B; }
 scalar_constant(A) ::= float_literal(B).   { A = B; }
 scalar_constant(A) ::= integer_literal(B). { A = B; }
 scalar_constant(A) ::= string_literal(B).  { A = B; }
-scalar_constant(A) ::= TRUE.     { A = CFCUtil_strdup("true"); }
-scalar_constant(A) ::= FALSE.    { A = CFCUtil_strdup("false"); }
-scalar_constant(A) ::= NULL.     { A = CFCUtil_strdup("NULL"); }
+scalar_constant(A) ::= TRUE.     { A = CFCParser_dupe(state, "true"); }
+scalar_constant(A) ::= FALSE.    { A = CFCParser_dupe(state, "false"); }
+scalar_constant(A) ::= NULL.     { A = CFCParser_dupe(state, "NULL"); }
 
 hex_literal(A)     ::= HEX_LITERAL(B).     { A = B; }
 float_literal(A)   ::= FLOAT_LITERAL(B).   { A = B; }
@@ -689,7 +672,6 @@ param_list_elems(A) ::= param_list_elems
     A = B;
     CFCParamList_add_param(A, C, D);
     CFCBase_decref((CFCBase*)C);
-    FREEMEM(D);
 }
 param_list_elems(A) ::= param_variable(B).
 {
@@ -702,7 +684,6 @@ param_list_elems(A) ::= param_variable(B
     A = CFCParamList_new(false);
     CFCParamList_add_param(A, B, C);
     CFCBase_decref((CFCBase*)B);
-    FREEMEM(C);
 }
 
 docucomment(A) ::= DOCUCOMMENT(B).
@@ -722,8 +703,9 @@ qualified_id(A) ::= identifier(B).
 
 qualified_id(A) ::= qualified_id(B) SCOPE_OP identifier(C).
 {
-    A = CFCUtil_cat(B, "::", C, NULL);
-    FREEMEM(C);
+    size_t size = strlen(B) + strlen(C) + 3;
+    A = (char*)CFCParser_allocate(state, size);
+    sprintf(A, "%s::%s", B, C);
 }
 
 class_inheritance(A) ::= INHERITS qualified_id(B).
@@ -739,7 +721,6 @@ cnick(A) ::= CNICK identifier(B).
 cblock(A) ::= CBLOCK_START blob(B) CBLOCK_CLOSE.
 {
     A = CFCCBlock_new(B);
-    FREEMEM(B);
 }
 
 blob(A) ::= BLOB(B).

Modified: incubator/lucy/branches/clownfish_lemon/clownfish/src/CFCParser.c
URL: http://svn.apache.org/viewvc/incubator/lucy/branches/clownfish_lemon/clownfish/src/CFCParser.c?rev=1188972&r1=1188971&r2=1188972&view=diff
==============================================================================
--- incubator/lucy/branches/clownfish_lemon/clownfish/src/CFCParser.c (original)
+++ incubator/lucy/branches/clownfish_lemon/clownfish/src/CFCParser.c Tue Oct 25 23:45:14 2011
@@ -23,6 +23,7 @@
 #include "CFCParcel.h"
 #include "CFCFile.h"
 #include "CFCUtil.h"
+#include "CFCMemPool.h"
 #include "CFCLexHeader.h"
 #include "CFCParseHeader.h"
 
@@ -50,6 +51,7 @@ struct CFCParser {
     char *class_name;
     char *class_cnick;
     char *source_class;
+    CFCMemPool *pool;
 };
 
 CFCParser*
@@ -70,6 +72,7 @@ CFCParser_init(CFCParser *self) {
     self->class_name   = NULL;
     self->class_cnick  = NULL;
     self->source_class = NULL;
+    self->pool         = NULL;
     return self;
 }
 
@@ -78,6 +81,7 @@ CFCParser_destroy(CFCParser *self) {
     CFCParseHeaderFree(self->header_parser, free);
     FREEMEM(self->class_name);
     FREEMEM(self->class_cnick);
+    CFCBase_decref((CFCBase*)self->pool);
     CFCBase_decref(self->result);
     CFCBase_destroy((CFCBase*)self);
 }
@@ -88,6 +92,8 @@ CFCParcel *CFCParser_current_parcel = NU
 
 CFCBase*
 CFCParser_parse(CFCParser *self, const char *string) {
+    self->pool = CFCMemPool_new(0);
+
     // Make Lemon-based parser and parser state available from Flex-based scanner.
     CFCParser_current_state  = self;
     CFCParser_current_parser = self->header_parser;
@@ -100,6 +106,8 @@ CFCParser_parse(CFCParser *self, const c
 
     // Finish up.
     CFCParseHeader(CFCParser_current_parser, 0, NULL, self);
+    CFCBase_decref((CFCBase*)self->pool);
+    self->pool = NULL;
     CFCBase *result = self->result;
     self->result = NULL;
     if (self->errors) {
@@ -121,6 +129,19 @@ CFCParser_parse_file(CFCParser *self, co
     return result;
 }
 
+char*
+CFCParser_dupe(CFCParser *self, const char *string) {
+    size_t len = strlen(string);
+    char *dupe = CFCMemPool_allocate(self->pool, len + 1);
+    memcpy(dupe, string, len + 1);
+    return dupe;
+}
+
+void*
+CFCParser_allocate(CFCParser *self, size_t size) {
+    return CFCMemPool_allocate(self->pool, size);
+}
+
 void
 CFCParser_set_result(CFCParser *self, CFCBase *result)
 {

Modified: incubator/lucy/branches/clownfish_lemon/clownfish/src/CFCParser.h
URL: http://svn.apache.org/viewvc/incubator/lucy/branches/clownfish_lemon/clownfish/src/CFCParser.h?rev=1188972&r1=1188971&r2=1188972&view=diff
==============================================================================
--- incubator/lucy/branches/clownfish_lemon/clownfish/src/CFCParser.h (original)
+++ incubator/lucy/branches/clownfish_lemon/clownfish/src/CFCParser.h Tue Oct 25 23:45:14 2011
@@ -45,6 +45,12 @@ struct CFCFile*
 CFCParser_parse_file(CFCParser *self, const char *string,
                      const char *source_class);
 
+char*
+CFCParser_dupe(CFCParser *self, const char *string);
+
+void*
+CFCParser_allocate(CFCParser *self, size_t size);
+
 void
 CFCParser_set_result(CFCParser *self, struct CFCBase *result);