mirror of
https://github.com/boostorg/build.git
synced 2026-02-02 20:52:13 +00:00
138 lines
2.5 KiB
C
138 lines
2.5 KiB
C
/*
|
|
* Copyright 1993, 2000 Christopher Seiwald.
|
|
*
|
|
* This file is part of Jam - see jam.c for Copyright information.
|
|
*/
|
|
|
|
/* This file is ALSO:
|
|
* Copyright 2001-2004 David Abrahams.
|
|
* Distributed under the Boost Software License, Version 1.0.
|
|
* (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
|
|
# include "jam.h"
|
|
# include "lists.h"
|
|
# include "parse.h"
|
|
# include "scan.h"
|
|
# include "newstr.h"
|
|
# include "modules.h"
|
|
# include "frames.h"
|
|
|
|
/*
|
|
* parse.c - make and destroy parse trees as driven by the parser
|
|
*
|
|
* 09/07/00 (seiwald) - ref count on PARSE to avoid freeing when used,
|
|
* as per Matt Armstrong.
|
|
* 09/11/00 (seiwald) - structure reworked to reflect that (*func)()
|
|
* returns a LIST *.
|
|
*/
|
|
|
|
static PARSE *yypsave;
|
|
|
|
void
|
|
parse_file( char *f, FRAME* frame )
|
|
{
|
|
/* Suspend scan of current file */
|
|
/* and push this new file in the stream */
|
|
|
|
yyfparse(f);
|
|
|
|
/* Now parse each block of rules and execute it. */
|
|
/* Execute it outside of the parser so that recursive */
|
|
/* calls to yyrun() work (no recursive yyparse's). */
|
|
|
|
for(;;)
|
|
{
|
|
PARSE *p;
|
|
|
|
/* Filled by yyparse() calling parse_save() */
|
|
|
|
yypsave = 0;
|
|
|
|
/* If parse error or empty parse, outta here */
|
|
|
|
if( yyparse() || !( p = yypsave ) )
|
|
break;
|
|
|
|
/* Run the parse tree. */
|
|
|
|
parse_evaluate( p, frame );
|
|
parse_free( p );
|
|
}
|
|
}
|
|
|
|
void
|
|
parse_save( PARSE *p )
|
|
{
|
|
yypsave = p;
|
|
}
|
|
|
|
PARSE *
|
|
parse_make(
|
|
LIST *(*func)( PARSE *p, FRAME *args ),
|
|
PARSE *left,
|
|
PARSE *right,
|
|
PARSE *third,
|
|
char *string,
|
|
char *string1,
|
|
int num )
|
|
{
|
|
PARSE *p = (PARSE *)malloc( sizeof( PARSE ) );
|
|
|
|
p->func = func;
|
|
p->left = left;
|
|
p->right = right;
|
|
p->third = third;
|
|
p->string = string;
|
|
p->string1 = string1;
|
|
p->num = num;
|
|
p->refs = 1;
|
|
p->rulename = 0;
|
|
|
|
if ( left )
|
|
{
|
|
p->file = left->file;
|
|
p->line = left->line;
|
|
}
|
|
else
|
|
{
|
|
yyinput_stream( &p->file, &p->line );
|
|
}
|
|
|
|
return p;
|
|
}
|
|
|
|
void
|
|
parse_refer( PARSE *p )
|
|
{
|
|
++p->refs;
|
|
}
|
|
|
|
void
|
|
parse_free( PARSE *p )
|
|
{
|
|
if( --p->refs )
|
|
return;
|
|
|
|
if( p->string )
|
|
freestr( p->string );
|
|
if( p->string1 )
|
|
freestr( p->string1 );
|
|
if( p->left )
|
|
parse_free( p->left );
|
|
if( p->right )
|
|
parse_free( p->right );
|
|
if( p->third )
|
|
parse_free( p->third );
|
|
if ( p->rulename )
|
|
freestr( p->rulename );
|
|
|
|
free( (char *)p );
|
|
}
|
|
|
|
LIST* parse_evaluate( PARSE *p, FRAME* frame )
|
|
{
|
|
frame->procedure = p;
|
|
return (*p->func)(p, frame);
|
|
}
|