 /*
  * Khoros: $Id: matrix_yacc.y,v 1.1 1991/05/10 15:43:29 khoros Exp $
  */

 /*
  * $Log: matrix_yacc.y,v $
 * Revision 1.1  1991/05/10  15:43:29  khoros
 * Initial revision
 *
  */ 

%{

#include <stdio.h>
#include "vmath.h"
#include "matrix.h"
#include "y.tab.h"

extern double *real, *imag;
extern p_rows,p_cols;

int curcols=0,curpos=0,cursize = 0;
%}

%token MBEGIN MEND DELIMITER CBEGIN CEND NUMBER PLUS MINUS
%left UNARYMINUS
%left '+' '-'

%%
/*
** BEGINNING OF GRAMMAR
*/

list:	  /* nothing */
	| list matrix 
	| list error
		{ return(-2); }
	;

matrix:	  MBEGIN rows MEND 
	;

rows:	  row
		{ p_rows++;
		  curpos = p_cols*p_rows;
		  curcols = 0;
		}
	| rows DELIMITER row
		{ p_rows++;
		  curpos = p_cols*p_rows;
		  curcols = 0;
		}
	;

row:	  /*nothing*/ 
	| row element
		{ if(!addelement($2.real,$2.imag,curpos))return(-1); 
		  curpos++;
		  curcols++;
		  p_cols = MAX(p_cols,curcols);
		}
	;

element:  number
		{ $$.real = $1.real;
		  $$.imag = 0.0;
		}
	| CBEGIN number number CEND 
		{ $$.real = $2.real;
		  $$.imag = $3.real;
		}
	;

number:	  NUMBER
		{
		  $$.real = $1.real;
		}
	| MINUS NUMBER	%prec UNARYMINUS
		{
		  $$.real = 0.0 - $2.real;
		}
	| PLUS NUMBER
		{
		  $$.real = $2.real;
		}	
	;

/*
** END OF THE GRAMMAR
*/
%%

/***********************************************************************
*
*  Routine Name: yyerror()
*
*          Date: Wed Aug 15 15:14:53 MDT 1990
*        
*       Purpose: outputs error messages from yacc and lex generated code. 
*
*         Input: char *string - error message.
*
*        Output: nothing
*
*    Written By: Jeremy Worley 
*
* Modifications:
*
***********************************************************************/

int yyerror(string)
  char *string;
{
  return(0);
}


/***********************************************************************
*
*  Routine Name: addelement()
*
*          Date: Thu Oct 11 23:49:50 MDT 1990
*        
*       Purpose: adds an element to the real and imag arrays and
*		 allocates memory as necessary. 
*
*         Input: realpart: double - real part of element.
*		 imagpart: double - imaginary part of element. 
*		 position: int    - place to put the element.
*
*        Output: - 
*
*    Written By: Jeremy Worley 
*
* Modifications: 
*
***********************************************************************/

int addelement(realpart,imagpart,position)
    double realpart,imagpart;
    int position;
{
    if(position<0)return(0);

    if(real == NULL){
       real = (double *)malloc((position+ADJUST)*sizeof(double));
       if(real==NULL)return(0);
    }


    if(imag == NULL){
       imag = (double *)malloc((position+ADJUST)*sizeof(double));
       if(imag==NULL)return(0);
    }

    if(position>=cursize){
       real = (double *)realloc((char *)real,(position+ADJUST)*sizeof(double));
       if(real==NULL)return(0);
       imag = (double *)realloc((char *)imag,(position+ADJUST)*sizeof(double));
       if(imag==NULL)return(0);
       cursize += ADJUST;
    }

    imag[position] = imagpart;
    real[position] = realpart;
   
    return(1);
} 

/***********************************************************************
*
*  Routine Name: mparse_init()
*
*          Date: Thu Oct 11 23:49:50 MDT 1990
*        
*    Written By: Jeremy Worley 
*
* Modifications: 
*
***********************************************************************/
int mparse_init()
{
 curcols=0,curpos=0,cursize = 0;
}

