1/* 2 * Copyright 1993, 2000 Christopher Seiwald. 3 * 4 * This file is part of Jam - see jam.c for Copyright information. 5 */ 6 7/* 8 * parse.c - make and destroy parse trees as driven by the parser 9 * 10 * 09/07/00 (seiwald) - ref count on PARSE to avoid freeing when used, 11 * as per Matt Armstrong. 12 * 09/11/00 (seiwald) - structure reworked to reflect that (*func)() 13 * returns a LIST *. 14 * 10/22/02 (seiwald) - working return/break/continue statements 15 * 11/04/02 (seiwald) - const-ing for string literals 16 */ 17 18# include "jam.h" 19# include "lists.h" 20# include "parse.h" 21# include "scan.h" 22# include "newstr.h" 23# include "compile.h" 24 25static PARSE *yypsave; 26 27void 28parse_file( const char *f ) 29{ 30 /* Suspend scan of current file */ 31 /* and push this new file in the stream */ 32 33 yyfparse(f); 34 35 /* Now parse each block of rules and execute it. */ 36 /* Execute it outside of the parser so that recursive */ 37 /* calls to yyrun() work (no recursive yyparse's). */ 38 39 for(;;) 40 { 41 LOL l; 42 PARSE *p; 43 int jmp = 0; /* JMP_NONE */ 44 45 /* $(<) and $(>) empty in outer scope. */ 46 47 lol_init( &l ); 48 49 /* Filled by yyparse() calling parse_save() */ 50 51 yypsave = 0; 52 53 /* If parse error or empty parse, outta here */ 54 55 if( yyparse() || !( p = yypsave ) ) 56 break; 57 58 /* Run the parse tree. */ 59 60 list_free( (*(p->func))( p, &l, &jmp ) ); 61 62 parse_free( p ); 63 64 if ( jmp == JMP_EOF ) 65 break; 66 } 67} 68 69void 70parse_save( PARSE *p ) 71{ 72 yypsave = p; 73} 74 75PARSE * 76parse_make( 77 LIST *(*func)( PARSE *p, LOL *args, int *jmp ), 78 PARSE *left, 79 PARSE *right, 80 PARSE *third, 81 const char *string, 82 const char *string1, 83 int num ) 84{ 85 PARSE *p = (PARSE *)malloc( sizeof( PARSE ) ); 86 87 p->func = func; 88 p->left = left; 89 p->right = right; 90 p->third = third; 91 p->string = string; 92 p->string1 = string1; 93 p->num = num; 94 p->refs = 1; 95 96 return p; 97} 98 99void 100parse_refer( PARSE *p ) 101{ 102 ++p->refs; 103} 104 105void 106parse_free( PARSE *p ) 107{ 108 if( --p->refs ) 109 return; 110 111 if( p->string ) 112 freestr( p->string ); 113 if( p->string1 ) 114 freestr( p->string1 ); 115 if( p->left ) 116 parse_free( p->left ); 117 if( p->right ) 118 parse_free( p->right ); 119 if( p->third ) 120 parse_free( p->third ); 121 122 free( (char *)p ); 123} 124