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

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include "mpdefs.h"
#include "MissionPlan.h"
#include "BehaviorFactory.h"
#include "Syslog.h"

Boolean debug = False;


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

char parseErrorBuf[512];

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

/* Function prototypes */
int mplanFileLineNo();


void clearInputs();

BehaviorStack *_behaviorStack;
BehaviorFactory *_behaviorFactory = BehaviorFactory::instanceOf();
Behavior *_behavior = 0;

AttributeInputs attributeInputs;

#line 40 "missionPlan.y"
typedef union 
{
  int integer;
  char *string;
} YYSTYPE;
#line 48 "missionPlan.tab.c"
#define Word 257
#define BehaviorTag 258
#define YYERRCODE 256
short yylhs[] = {                                        -1,
    0,    1,    1,    2,    4,    4,    5,    3,
};
short yylen[] = {                                         2,
    1,    2,    1,    3,    1,    2,    4,    3,
};
short yydefred[] = {                                      0,
    0,    0,    0,    3,    0,    0,    2,    0,    0,    5,
    8,    0,    4,    6,    0,    7,
};
short yydgoto[] = {                                       2,
    3,    4,    5,    9,   10,
};
short yysindex[] = {                                   -257,
 -255,    0, -257,    0, -254, -119,    0,  -56, -125,    0,
    0, -251,    0,    0,  -52,    0,
};
short yyrindex[] = {                                      0,
    0,    0,    8,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,
};
short yygindex[] = {                                      0,
    0,    6,    0,    0,    1,
};
#define YYTABLESIZE 132
short yytable[] = {                                      13,
    1,    6,    8,   11,   12,   15,   16,    1,    7,   14,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    8,
};
short yycheck[] = {                                     125,
  258,  257,  257,  123,   61,  257,   59,    0,    3,    9,
   -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,   -1,
   -1,  257,
};
#define YYFINAL 2
#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",
"BehaviorTag",
};
char *yyrule[] = {
"$accept : MissionPlan",
"MissionPlan : Behaviors",
"Behaviors : Behaviors Behavior",
"Behaviors : Behavior",
"Behavior : StartBehavior Attributes '}'",
"Attributes : Attribute",
"Attributes : Attributes Attribute",
"Attribute : Word '=' Word ';'",
"StartBehavior : BehaviorTag 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 158 "missionPlan.y"

extern char *yytext;

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


void clearInputs()
{

  for (int i = 0; i < attributeInputs.size(); i++) {
    Attribute::Input *input;
    attributeInputs.get(i, &input);
    delete input;
  }

  attributeInputs.clear();
}


void MissionPlan::parse(FILE *fp, BehaviorStack *behaviorStack, 
			Boolean *error, char *errorMsg)
{
  int ret;
  extern FILE *yyin;

  _behaviorStack = behaviorStack;

  if (_behaviorStack) {
    _behaviorStack->clear();
  }

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

#line 213 "missionPlan.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 52 "missionPlan.y"
{
}
break;
case 2:
#line 57 "missionPlan.y"
{
}
break;
case 3:
#line 62 "missionPlan.y"
{
}
break;
case 4:
#line 67 "missionPlan.y"
{
  dprintf("Finished parsing Behavior %s\n", _behavior->name());

  Boolean error = False;
  for (int i = 0; i < attributeInputs.size(); i++) {
    Attribute::Input *input;
    attributeInputs.get(i, &input);

    if (_behavior->attributes.parse(input) == -1) {
      error = True;
    }
  }

  if (error) {
    sprintf(parseErrorBuf, "Parse failed for one or more attribute inputs");
    return errorReturn;
  }

  if (_behavior->attributes.verify() == -1) {
    sprintf(parseErrorBuf, "verify() failed for behavior %s\n", 
	    _behavior->name());
    error = True;
  }

  if (!_behavior->validInput()) {
    sprintf(parseErrorBuf, "validInput() failed for behavior %s\n", 
	    _behavior->name());

    error = True;    
  }

  if (!error ) {

    /* Add to stack*/
    _behaviorStack->add(&_behavior);
  }
  else {
    return errorReturn;
  }
}
break;
case 5:
#line 110 "missionPlan.y"
{
  dprintf("Attributes\n");
}
break;
case 6:
#line 116 "missionPlan.y"
{
  dprintf("Attributes\n");
}
break;
case 7:
#line 122 "missionPlan.y"
{
  dprintf("Got Attribute:  %s = %s\n", yyvsp[-3].string , yyvsp[-1].string );

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

  if (_behavior->attributes.parse(input) == -1) {
    sprintf(parseErrorBuf, 
	    "Line %d: Invalid attribute for behavior %s: \"%s\"", 
	    mplanFileLineNo(), _behavior->name(), input->name);

    return errorReturn;
  }

  attributeInputs.add(&input);
}
break;
case 8:
#line 140 "missionPlan.y"
{
  dprintf("StartBehavior %s\n", yyvsp[-1].string );
  const char *behaviorName = yyvsp[-1].string ;

  clearInputs();

  if ((_behavior = _behaviorFactory->create(behaviorName)) == 0) {

    sprintf(parseErrorBuf, "Line %d: Unknown behavior type name: \"%s\"\n",
	    mplanFileLineNo(), behaviorName);

    return errorReturn;
  }
}
break;
#line 458 "missionPlan.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);
}
