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