use left recursion instead of right recursion to avoid memory exhausted issue when compiling large source files

This commit is contained in:
Zou Nan hai 2010-04-21 11:02:21 +08:00 committed by Damien Lespiau
parent dea75a6935
commit db8aedc745
2 changed files with 26 additions and 12 deletions

View File

@ -122,6 +122,7 @@ struct brw_program_instruction {
*/ */
struct brw_program { struct brw_program {
struct brw_program_instruction *first; struct brw_program_instruction *first;
struct brw_program_instruction *last;
}; };
extern struct brw_program compiled_program; extern struct brw_program compiled_program;

View File

@ -174,16 +174,15 @@ ROOT: instrseq
label: STRING COLON label: STRING COLON
; ;
instrseq: instruction SEMICOLON instrseq instrseq: instrseq instruction SEMICOLON
{ {
struct brw_program_instruction *list_entry = struct brw_program_instruction *list_entry =
calloc(sizeof(struct brw_program_instruction), 1); calloc(sizeof(struct brw_program_instruction), 1);
list_entry->instruction = $1; list_entry->instruction = $2;
list_entry->next = NULL;
list_entry->next = $3.first; $1.last->next = list_entry;
$3.first = list_entry; $1.last = list_entry;
$$ = $1;
$$ = $3;
} }
| instruction SEMICOLON | instruction SEMICOLON
{ {
@ -194,16 +193,30 @@ instrseq: instruction SEMICOLON instrseq
list_entry->next = NULL; list_entry->next = NULL;
$$.first = list_entry; $$.first = list_entry;
$$.last = list_entry;
} }
| label instrseq | instrseq label
{
struct brw_program_instruction *list_entry =
calloc(sizeof(struct brw_program_instruction), 1);
list_entry->string = strdup($2);
list_entry->islabel = 1;
list_entry->next = NULL;
$1.last->next = list_entry;
$1.last = list_entry;
$$ = $1;
}
| label
{ {
struct brw_program_instruction *list_entry = struct brw_program_instruction *list_entry =
calloc(sizeof(struct brw_program_instruction), 1); calloc(sizeof(struct brw_program_instruction), 1);
list_entry->string = strdup($1); list_entry->string = strdup($1);
list_entry->islabel = 1; list_entry->islabel = 1;
list_entry->next = $2.first;
$2.first = list_entry; list_entry->next = NULL;
$$ = $2;
$$.first = list_entry;
$$.last = list_entry;
} }
| error SEMICOLON instrseq | error SEMICOLON instrseq
{ {