#ifndef lint
char yysccsid[] = "@(#)yaccpar	1.4 (Berkeley) 02/25/90";
#endif
#line 2 "parseComplex.y"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "Syslog.h"
#include "Attributes.h"
#include "Item.h"
#include "ItemList.h"  

Boolean debug;

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

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

Attributes *_attributes;

Item *_curItem;
ItemList *_itemList;

char _errorBuf[512];

void restartLexer();
Boolean isIdentifier( const char *testMe );

#line 35 "parseComplex.y"
typedef union 
{
  int integer;
  char *string;
} YYSTYPE;
#line 43 "parseComplex.tab.c"
#define Word 257
#define Identifier 258
#define YYERRCODE 256
short yylhs[] = {                                        -1,
    0,    1,    1,    2,    2,    3,    5,    6,    6,    4,
};
short yylen[] = {                                         2,
    1,    1,    2,    1,    1,    3,    3,    1,    2,    4,
};
short yydefred[] = {                                      0,
    0,    0,    0,    0,    2,    4,    5,    0,    0,    0,
    3,    8,    0,    0,    7,    6,    9,   10,
};
short yydgoto[] = {                                       3,
    4,    5,    6,    7,    8,   13,
};
short yysindex[] = {                                   -255,
  -57, -252,    0, -255,    0,    0,    0, -250, -249, -114,
    0,    0, -125,  -49,    0,    0,    0,    0,
};
short yyrindex[] = {                                      0,
    0,    0,    0,   11,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,
};
short yygindex[] = {                                      0,
    0,    8,    0,   -7,    0,    0,
};
#define YYTABLESIZE 132
short yytable[] = {                                      16,
   12,    1,    2,    9,   10,   17,    1,   14,   15,   18,
    1,   11,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    1,
};
short yycheck[] = {                                     125,
    8,  257,  258,   61,  257,   13,  257,  257,  123,   59,
    0,    4,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,  257,
};
#define YYFINAL 3
#ifndef YYDEBUG
#define YYDEBUG 0
#endif
#define YYMAXTOKEN 258
#if YYDEBUG
char *yyname[] = {
"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"';'",0,"'='",0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,"'{'",0,"'}'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"Word",
"Identifier",
};
char *yyrule[] = {
"$accept : ConfigFile",
"ConfigFile : Units",
"Units : Unit",
"Units : Units Unit",
"Unit : Item",
"Unit : Attribute",
"Item : StartItem Attributes '}'",
"StartItem : Identifier Word '{'",
"Attributes : Attribute",
"Attributes : Attributes Attribute",
"Attribute : Word '=' Word ';'",
};
#endif
#define yyclearin (yychar=(-1))
#define yyerrok (yyerrflag=0)
#ifndef YYSTACKSIZE
#ifdef YYMAXDEPTH
#define YYSTACKSIZE YYMAXDEPTH
#else
#define YYSTACKSIZE 300
#endif
#endif
int yydebug;
int yynerrs;
int yyerrflag;
int yychar;
short *yyssp;
YYSTYPE *yyvsp;
YYSTYPE yyval;
YYSTYPE yylval;
#define yystacksize YYSTACKSIZE
short yyss[YYSTACKSIZE];
YYSTYPE yyvs[YYSTACKSIZE];
#line 153 "parseComplex.y"

extern char *yytext;

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

void resetComplex()
{
     _curItem = NULL;
     _attributes = NULL;
     _itemList = NULL;
}

// Used in the Lexer
Boolean isIdentifier( const char *testMe )
{
//     Boolean debug = False;

     dprintf("isIdentifier -- I've been asked to test the word %s",
	     testMe );
   
     if( _itemList != NULL )
     {
//	  return  _itemList->isIdentifier( testMe );
	  if( _itemList->isIdentifier( testMe ) )
	  {
	       dprintf("isidentifier -- %s matches",
		       _itemList->identifier() );
	       return True;
	  }
	  else
	  {
	       dprintf("isIdentifier -- %s doesn't match",
		       _itemList->identifier() );
	       return False;
	  }
	       
     }

     return False;
}

void parseComplex(FILE *fp, 
		  Attributes *attributes,
		  ItemList *itemList,
		  Boolean *error, char *errorMsg,
		  Boolean debugIn)
{
  int ret;
  extern FILE *yyin;
  
  restartLexer();

  _attributes = attributes;
  _itemList = itemList;

  *error = False;
  yyin = fp;

  debug = debugIn;

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

  return;
}

#line 236 "parseComplex.tab.c"
#define YYABORT goto yyabort
#define YYACCEPT goto yyaccept
#define YYERROR goto yyerrlab
int
yyparse()
{
    register int yym, yyn, yystate;
#if YYDEBUG
    register char *yys;
    extern char *getenv();

    if (yys = getenv("YYDEBUG"))
    {
        yyn = *yys;
        if (yyn >= '0' && yyn <= '9')
            yydebug = yyn - '0';
    }
#endif

    yynerrs = 0;
    yyerrflag = 0;
    yychar = (-1);

    yyssp = yyss;
    yyvsp = yyvs;
    *yyssp = yystate = 0;

yyloop:
    if (yyn = yydefred[yystate]) goto yyreduce;
    if (yychar < 0)
    {
        if ((yychar = yylex()) < 0) yychar = 0;
#if YYDEBUG
        if (yydebug)
        {
            yys = 0;
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
            if (!yys) yys = "illegal-symbol";
            printf("yydebug: state %d, reading %d (%s)\n", yystate,
                    yychar, yys);
        }
#endif
    }
    if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
    {
#if YYDEBUG
        if (yydebug)
            printf("yydebug: state %d, shifting to state %d\n",
                    yystate, yytable[yyn]);
#endif
        if (yyssp >= yyss + yystacksize - 1)
        {
            goto yyoverflow;
        }
        *++yyssp = yystate = yytable[yyn];
        *++yyvsp = yylval;
        yychar = (-1);
        if (yyerrflag > 0)  --yyerrflag;
        goto yyloop;
    }
    if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
    {
        yyn = yytable[yyn];
        goto yyreduce;
    }
    if (yyerrflag) goto yyinrecovery;
#ifdef lint
    goto yynewerror;
#endif
yynewerror:
    yyerror("syntax error");
#ifdef lint
    goto yyerrlab;
#endif
yyerrlab:
    ++yynerrs;
yyinrecovery:
    if (yyerrflag < 3)
    {
        yyerrflag = 3;
        for (;;)
        {
            if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
                    yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
            {
#if YYDEBUG
                if (yydebug)
                    printf("yydebug: state %d, error recovery shifting\
 to state %d\n", *yyssp, yytable[yyn]);
#endif
                if (yyssp >= yyss + yystacksize - 1)
                {
                    goto yyoverflow;
                }
                *++yyssp = yystate = yytable[yyn];
                *++yyvsp = yylval;
                goto yyloop;
            }
            else
            {
#if YYDEBUG
                if (yydebug)
                    printf("yydebug: error recovery discarding state %d\n",
                            *yyssp);
#endif
                if (yyssp <= yyss) goto yyabort;
                --yyssp;
                --yyvsp;
            }
        }
    }
    else
    {
        if (yychar == 0) goto yyabort;
#if YYDEBUG
        if (yydebug)
        {
            yys = 0;
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
            if (!yys) yys = "illegal-symbol";
            printf("yydebug: state %d, error recovery discards token %d (%s)\n",
                    yystate, yychar, yys);
        }
#endif
        yychar = (-1);
        goto yyloop;
    }
yyreduce:
#if YYDEBUG
    if (yydebug)
        printf("yydebug: state %d, reducing by rule %d (%s)\n",
                yystate, yyn, yyrule[yyn]);
#endif
    yym = yylen[yyn];
    yyval = yyvsp[1-yym];
    switch (yyn)
    {
case 1:
#line 47 "parseComplex.y"
{
}
break;
case 2:
#line 51 "parseComplex.y"
{
}
break;
case 3:
#line 55 "parseComplex.y"
{
}
break;
case 4:
#line 60 "parseComplex.y"
{
}
break;
case 5:
#line 64 "parseComplex.y"
{
}
break;
case 6:
#line 68 "parseComplex.y"
{
     dprintf("Finished parsing item %s", _curItem->name());
     _curItem = NULL;
}
break;
case 7:
#line 74 "parseComplex.y"
{
     if( _itemList == NULL )
     {
	  Syslog::write("Parser has found inappropriate identifier");
	  return errorReturn;
     }

     dprintf("Parsing new item of type: %s named %s\n",
	     _itemList->identifier(), yyvsp[-1].string  );
     
     if( (_curItem = _itemList->addItem( yyvsp[-1].string  )) == NULL ) 
     {
	  dprintf("Something went wrong adding a new item called %s",
		  yyvsp[-1].string  );
     }

}
break;
case 8:
#line 93 "parseComplex.y"
{
}
break;
case 9:
#line 98 "parseComplex.y"
{
}
break;
case 10:
#line 103 "parseComplex.y"
{
  dprintf("Parsing attribute %s = %s", yyvsp[-3].string , yyvsp[-1].string  );

  Attributes *curAttributes = NULL;

  Attribute::Input *input = new Attribute::Input(yyvsp[-3].string , yyvsp[-1].string );

  Boolean error = False;

/*  dprintf("Parsing attribute %s = %s", $1, $3 );*/

  if( _curItem != NULL ) {
       dprintf("Using the current item %s",
	       _curItem->name() );
       curAttributes = _curItem->attributes();

       dprintf("Using the attribute set %s from item  %s\n",
	       curAttributes->objectName(),
	       _curItem->name() );
  }
  else if( _attributes != NULL ) {
       dprintf("No current item .. using the provided attributes %s",
	       _attributes->objectName() );
       curAttributes = _attributes;
  }
  else
  {
       Syslog::write("complexParser -- Found ungrouped attributes in the "
		     "wrong place.");
       return errorReturn;
  }

  if (curAttributes->parse(input) == -1) {

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

      error = True;
  }

  delete input;

  if (error)
    return errorReturn;
}
break;
#line 487 "parseComplex.tab.c"
    }
    yyssp -= yym;
    yystate = *yyssp;
    yyvsp -= yym;
    yym = yylhs[yyn];
    if (yystate == 0 && yym == 0)
    {
#ifdef YYDEBUG
        if (yydebug)
            printf("yydebug: after reduction, shifting from state 0 to\
 state %d\n", YYFINAL);
#endif
        yystate = YYFINAL;
        *++yyssp = YYFINAL;
        *++yyvsp = yyval;
        if (yychar < 0)
        {
            if ((yychar = yylex()) < 0) yychar = 0;
#if YYDEBUG
            if (yydebug)
            {
                yys = 0;
                if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
                if (!yys) yys = "illegal-symbol";
                printf("yydebug: state %d, reading %d (%s)\n",
                        YYFINAL, yychar, yys);
            }
#endif
        }
        if (yychar == 0) goto yyaccept;
        goto yyloop;
    }
    if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
            yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
        yystate = yytable[yyn];
    else
        yystate = yydgoto[yym];
#ifdef YYDEBUG
    if (yydebug)
        printf("yydebug: after reduction, shifting from state %d \
to state %d\n", *yyssp, yystate);
#endif
    if (yyssp >= yyss + yystacksize - 1)
    {
        goto yyoverflow;
    }
    *++yyssp = yystate;
    *++yyvsp = yyval;
    goto yyloop;
yyoverflow:
    yyerror("yacc stack overflow");
yyabort:
    return (1);
yyaccept:
    return (0);
}
