File: parse.c

package info (click to toggle)
jam 2.6-1
  • links: PTS, VCS
  • area: main
  • in suites: buster, jessie, jessie-kfreebsd, stretch
  • size: 1,316 kB
  • ctags: 1,068
  • sloc: ansic: 7,827; yacc: 443; sh: 63; makefile: 48
file content (134 lines) | stat: -rw-r--r-- 2,527 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
 * Copyright 1993, 2000 Christopher Seiwald.
 *
 * This file is part of Jam - see jam.c for Copyright information.
 */

/*
 * 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 *.
 * 10/22/02 (seiwald) - working return/break/continue statements
 * 11/04/02 (seiwald) - const-ing for string literals
 * 01/05/07 (seiwald) - new yyfname/yylineno for DEBUG_COMPILE
 */

# include "jam.h"
# include "lists.h"
# include "parse.h"
# include "scan.h"
# include "newstr.h"

static PARSE *yypsave;

void
parse_file( const char *f )
{
	/* 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(;;)
	{
	    LOL l;
	    PARSE *p;
	    int jmp = 0; /* JMP_NONE */

	    /* $(<) and $(>) empty in outer scope. */

	    lol_init( &l );

	    /* 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. */

	    list_free( (*(p->func))( p, &l, &jmp ) );

	    parse_free( p );
	}
}

void
parse_save( PARSE *p )
{
	yypsave = p;
}

PARSE *
parse_make( 
	LIST		*(*func)( PARSE *p, LOL *args, int *jmp ),
	PARSE		*left,
	PARSE		*right,
	PARSE		*third,
	const char 	*string,
	const 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->yyfname = 0;
	p->yylineno = 0;

	/* Only worth it for debugging. */
	/* Don't label intermediate nodes. */
	/* debug_compile() finds first labelled node. */

	if( DEBUG_COMPILE && !p->left && !p->right )
	{
	    p->yyfname = yyfname();
	    p->yylineno = yylineno();
	}

	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->yyfname )
	    freestr( p->yyfname );
	
	free( (char *)p );
}