/*
**      w3_yacc.y     -
**
**
** Copyright (c) 1995  Hughes Technologies Pty Ltd
**
** Permission to use, copy, and distribute for non-commercial purposes,
** is hereby granted without fee, providing that the above copyright
** notice appear in all copies and that both the copyright notice and this
** permission notice appear in supporting documentation.
**
** The software may be modified for your own purposes, but modified versions
** may not be distributed.
**
** This software is provided "as is" without any expressed or implied warranty.
**
*/


%{
#include <stdio.h>
#include <sys/types.h>
#include <msql.h>

#ifdef OS2
#  include <common\config.h>
#  include <common\portable.h>
#endif

#include "w3-msql.h"


#define YYDEBUG 1

int     doingSet = 0;

%}

%token  END_OF_INPUT

%token  GE
%token  LE
%token  NE
%token  EQ
%token  GT
%token  LT
%token  RE

%token  ADD
%token  SUB
%token  MUL
%token  DIV

%token  LOGICAL_OR
%token  LOGICAL_AND

%token  OPEN_BRACKET
%token  CLOSE_BRACKET

%token CONNECT
%token CONVERT
%token CLOSE
%token QUERY
%token FREE
%token PRINT
%token PRINT_ROWS
%token FETCH
%token SEEK
%token DATABASE
%token SET
%token SETDEFAULT
%token TRANSLATE
%token TAG_CLOSE

%token IF
%token ELSE
%token FI

%token STRING
%token IDENT
%token TEXT
%token NUM
%token VAR
%token UNKNOWN
%token VARIABLE
%token CHAR

%%

page
        : commands END_OF_INPUT
          {
                sendFooter();
          }


commands
        : /* NULL */
        | connect commands
        | close commands
        | query commands
        | free commands
        | print commands
        | print_rows commands
        | fetch commands
        | seek commands
        | database commands
        | {doingSet=1;} convert commands
        | {doingSet=1;} set commands
        | {doingSet=1;} setdefault commands
        | if commands
        | else commands
        | fi commands
        | translate commands

connect
        : CONNECT IDENT TAG_CLOSE
          {
                if (checkIf())
                        doConnect($2);
          }
        | CONNECT TEXT TAG_CLOSE
          {
                if (checkIf())
                        doConnect($2);
          }
        | CONNECT TAG_CLOSE
          {
                if (checkIf())
                        doConnect(NULL);
          }

close
        : CLOSE TAG_CLOSE
          {
                if (checkIf())
                        doClose();
          }

database
        : DATABASE IDENT TAG_CLOSE
          {
                if (checkIf())
                        doDatabase($2);
          }

query
        : QUERY TEXT IDENT TAG_CLOSE
          {
                if (checkIf())
                        doQuery($2, $3);
          }

free
        : FREE IDENT TAG_CLOSE
          {
                if (checkIf())
                        doFree($2);
          }

print
        : PRINT TEXT TAG_CLOSE
          {
                if (checkIf())
                        doField($2);
          }

fetch
        : FETCH IDENT TAG_CLOSE
          {
                if (checkIf())
                        doFetch($2);
          }


seek
        : SEEK IDENT NUM TAG_CLOSE
          {
                if (checkIf())
                        doSeek($2, $3);
          }

print_rows
        : PRINT_ROWS IDENT TEXT TAG_CLOSE
          {
                if (checkIf())
                        doPrintRows($2,$3);
          }

translate
        : TRANSLATE VAR CHAR CHAR TAG_CLOSE
          {
                if (checkIf())
                        doTranslate($2, $3, $4);
          }
if
        :
          {
                startIf();
          }
        IF  '(' condition ')' TAG_CLOSE
          {
                endIfCond();
          }

else
        : ELSE TAG_CLOSE
          {
                doElse();
          }

fi
        : FI TAG_CLOSE
          {
                endIf();
          }



condition
        : expr condition_expr
        | '(' condition ')' logical '(' condition ')'
          {
                if(checkIf())
                        doLogical($4);
          }


condition_expr
        : cond_op expr
          {
                if(checkIf())
                        doComparison($1);
          }
        | /*  NULL*/
          {
                if(checkIf())
                {
                        addValue(strdup("0"),NUM);
                        doComparison(NE);
                }
          }



logical
        : /* NULL */
        | LOGICAL_OR
          {
                $$ = (u_char *)LOGICAL_OR;
          }

        | LOGICAL_AND
          {
                $$ = (u_char *)LOGICAL_AND;
          }



convert
        : CONVERT VAR TAG_CLOSE
          {
                if (checkIf())
                {
                        convertVariable($2);
                        doingSet = 0;
                }
          }

set
        : SET VAR '=' expr TAG_CLOSE
          {
                if (checkIf())
                {
                        doSet($2);
                        doingSet = 0;
                }
          }

setdefault
        : SETDEFAULT VAR '=' expr TAG_CLOSE
          {
                if (checkIf())
                {
                        doSetDefault($2);
                        doingSet = 0;
                }
          }

expr
        : value
        | expr math_op expr
          {
                doMath($2);
          }
        | '(' expr ')'


math_op
        : '*'
          {
                $$ = (u_char *) MUL;
          }
        | '+'
          {
                $$ = (u_char *) ADD;
          }
        | '-'
          {
                $$ = (u_char *) SUB;
          }
        | '/'
          {
                $$ = (u_char *) DIV;
          }

value
        : VAR
          {
                if(checkIf()  || doingSet)
                        addValue($1,VAR);
          }
        | '@' IDENT '.' NUM
          {
                if(checkIf() || doingSet)
                        addRowValue($2,$4);
          }
        | TEXT
          {
                if(checkIf() || doingSet )
                        addValue($1,TEXT);
          }
        | NUM
          {
                if(checkIf() || doingSet)
                        addValue($1,NUM);
          }


cond_op
        : EQ
          {
                $$ = (u_char *) EQ;
          }
        | LT
          {
                $$ = (u_char *) LT;
          }
        | GT
          {
                $$ = (u_char *) GT;
          }
        | GE
          {
                $$ = (u_char *) GE;
          }
        | LE
          {
                $$ = (u_char *) LE;
          }
        | NE
          {
                $$ = (u_char *) NE;
          }
        | RE
          {
                $$ = (u_char *) RE;
          }

