From db8aedc745faea10b10f96b2dca9e29543192e68 Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Wed, 21 Apr 2010 11:02:21 +0800 Subject: [PATCH] use left recursion instead of right recursion to avoid memory exhausted issue when compiling large source files --- assembler/src/gen4asm.h | 1 + assembler/src/gram.y | 37 +++++++++++++++++++++++++------------ 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/assembler/src/gen4asm.h b/assembler/src/gen4asm.h index a965d112..c67d94ed 100644 --- a/assembler/src/gen4asm.h +++ b/assembler/src/gen4asm.h @@ -122,6 +122,7 @@ struct brw_program_instruction { */ struct brw_program { struct brw_program_instruction *first; + struct brw_program_instruction *last; }; extern struct brw_program compiled_program; diff --git a/assembler/src/gram.y b/assembler/src/gram.y index 4d061f30..438559a2 100644 --- a/assembler/src/gram.y +++ b/assembler/src/gram.y @@ -174,16 +174,15 @@ ROOT: instrseq label: STRING COLON ; -instrseq: instruction SEMICOLON instrseq +instrseq: instrseq instruction SEMICOLON { struct brw_program_instruction *list_entry = calloc(sizeof(struct brw_program_instruction), 1); - list_entry->instruction = $1; - - list_entry->next = $3.first; - $3.first = list_entry; - - $$ = $3; + list_entry->instruction = $2; + list_entry->next = NULL; + $1.last->next = list_entry; + $1.last = list_entry; + $$ = $1; } | instruction SEMICOLON { @@ -194,17 +193,31 @@ instrseq: instruction SEMICOLON instrseq list_entry->next = NULL; $$.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 = + calloc(sizeof(struct brw_program_instruction), 1); list_entry->string = strdup($1); list_entry->islabel = 1; - list_entry->next = $2.first; - $2.first = list_entry; - $$ = $2; - } + + list_entry->next = NULL; + + $$.first = list_entry; + $$.last = list_entry; + } | error SEMICOLON instrseq { $$ = $3;