/*
     extract - A network log processor
     Copyright (C) 1993 Douglas Lee Schales, David K. Hess, David R. Safford

     Please see the file `COPYING' for the complete copyright notice.

builder.c - 03/20/93

*/
#include <stdio.h>
#include <malloc.h>
#include "stdunix.h"

#include "parser.h"
#include "builder.h"

static struct parsenode *stack = 0;
int parse_error = 0;

struct parsenode *
popnode(void)
{
     struct parsenode *result;

     if(!stack){
	  fprintf(stderr, "\"%s\", line %d: parse tree stack underflow\n",
		  getfilename(), getlinenum());
	  exit(1);
     }
     result = stack;
     stack = result->next;

     return result;
}

void
pushval(unsigned long val)
{
     struct parsenode *node;
     node = (struct parsenode *)malloc(sizeof(struct parsenode));

     node->nodetype = VAL;
     node->nodeval = val;
     node->next = stack;
     stack = node;
}

void
pushkey(unsigned key)
{
     struct parsenode *node;
     node = (struct parsenode *)malloc(sizeof(struct parsenode));
     
     node->nodetype = KEY;
     node->nodeval = key;
     node->next = stack;
     stack = node;
}

void
pushoper(unsigned int oper)
{
     struct parsenode *node;

     node = (struct parsenode *)malloc(sizeof(struct parsenode));

     node->nodetype = OPER;
     node->nodeval = oper;
     node->rhs = popnode();
     node->lhs = popnode();

     node->next = stack;
     stack = node;
}

void
pushuoper(unsigned int oper)
{
     struct parsenode *node;

     node = (struct parsenode *)malloc(sizeof(struct parsenode));

     node->nodetype = UOPER;
     node->nodeval = oper;
     node->rhs = popnode();

     node->next = stack;
     stack = node;
}

struct actionlist *ahead = 0, *atail = 0;

void
queueact(int action)
{
     struct actionlist *anode;
     
     anode = (struct actionlist *)malloc(sizeof(struct actionlist));
     anode->action = action;
     anode->next = 0;
     if(atail)
	  atail->next = anode;
     else
	  ahead = anode;
     atail = anode;
}

struct parsetree *phead = 0, *ptail = 0;

void
queuestmt(void)
{
     struct parsetree *pt;

     pt = (struct parsetree *)malloc(sizeof(struct parsetree));
     
     pt->conditions = stack;
     pt->actions = ahead;
     pt->next = 0;
     ahead = atail = 0;
     stack = 0;

     if(ptail)
	  ptail->next = pt;
     else
	  phead = pt;
     ptail = pt;
}

struct parsetree *
parse(void)
{
     extern void yyparse(void);
     parse_error = 0;

     yyparse();
     if(!parse_error)
	  return phead;
     else
	  return 0;
}
