%{

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "WorkSite.h"
  
Boolean debug = False;

// Function prototypes
int yyerror(char *errorBuf);
int yylex();
int yyparse();
int fileLineNo();

const int eofReturn = -1;
const int errorReturn = 1;
const int okReturn = 0;

char _parseErrorBuf[512];
WorkSite *_workSite;
WorkSite::Transponder *_transponder = 0;


%}

%union 
{
  int integer;
  char *string;
}

%token <string> Word
%token TransponderTag 

%%

Entry :
{
  return eofReturn;
}


Entry : Attribute
{
  return okReturn;
}


Entry : Transponder 
{
  return okReturn;
}


Transponder : StartTransponder Attributes '}'
{
  if (_transponder->attributes.verify() == -1) {
    // Missing attributes?
    sprintf(_parseErrorBuf, "Missing transponder attributes");
    return errorReturn;
  }
  else
    _workSite->transponders.add(&_transponder);

  _transponder = 0;
}


StartTransponder : TransponderTag Word '{'
{
  _transponder = new WorkSite::Transponder();
}


Attributes: Attribute
{
};


Attributes: Attributes Attribute
{
};


Attribute : Word '=' Word ';'
{
  Attribute::Input *input = new Attribute::Input($1, $3);

  Boolean error = False;

  if (_transponder) {
    // In transponder specification
    if (_transponder->attributes.parse(input) == -1) {

      // Invalid transponder attribute
      sprintf(_parseErrorBuf, "Invalid transponder attribute: %s = %s",
	      $1, $3);

      error = True;
    }
  }

  else {
    // Worksite attribute (latitude, longitude, etc)
    if (_workSite->attributes.parse(input) == -1) {

      // Invalid worksite attribute
      sprintf(_parseErrorBuf, "Invalid Worksite attribute: %s = %s",
	      $1, $3);

      error = True;
    }
  }

  delete input;

  if (error)
    return errorReturn;
}




%%

extern char *yytext;

int yyerror(char *errorMsg)
{
  sprintf(_parseErrorBuf, 
	  "Line %d: %s\noffending text: \"%s\"", 
	  fileLineNo(), errorMsg, yytext);
  
  return 0;
}


void parseWorkSite(FILE *fp, WorkSite *workSite,
		   Boolean *error, char *errorMsg)
{
  _workSite = workSite;

  int ret;
  extern FILE *yyin;
  
  *error = False;
  yyin = fp;

  while (True) {

    if ((ret = yyparse()) != okReturn) {
      /* Error or end-of-file */
      if (ret == errorReturn) {
	*error = True;
	strcpy(errorMsg, _parseErrorBuf);
      }
      return;
    }
  }

  return;
}

