#include <ctype.h>
#include "fsm.h"
#define _TMPRFSM_get ((*(_TMPRFSM_inp->string))?(*++(_TMPRFSM_inp->string)):'\0')
#define _TMPRFSM_char (0x7f&(int)*(_TMPRFSM_inp->string))

static char *_TMPRFSM_lastfail;
static FSMarg _TMPRFSM_mainarg = { 0, 0 };

static char _TMPRFSM_anyof0[128] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,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,1,0,1,0,0,0,0,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,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

_TMPRFSM_(s)
char *s;
{
 int i;
#ifdef vax
 char *cp;
#endif

 _TMPRFSM_mainarg.string = s;
#ifdef vax
 cp = (char *) &s;
 if (cp[-4] >= 2) /* VAX SPECIFIC!!!! */
  { _TMPRFSM_mainarg.flags = ((int *)cp)[1];
  }
 else
#endif
  { _TMPRFSM_mainarg.flags = 0;
  }
 _TMPRFSM_lastfail = 0;
 i = __TMPRFSM_(&_TMPRFSM_mainarg,1);
 if (!i && _TMPRFSM_lastfail)
  { _TMPRFSM_mainarg.string = _TMPRFSM_lastfail;
  }
 return(i);
}

FSMarg *_TMPRFSM_getarg()
{
 return(&_TMPRFSM_mainarg);
}

char *_TMPRFSM_rest()
{
 return(_TMPRFSM_mainarg.string);
}

_TMPRFSM_cmp(in,str,want,buf)
FSMarg *in;
char *str;
char *want;
char *buf;
{
 register int i;
 char *start;
 register char *cp;

 cp = in->string;
 start = cp;
 for (i=0;str[i];i++) if (cp[i] != str[i]) return(0);
 cp += i;
 if (want)
  { for (i=0;want[i];i++) if (cp[i] != want[i]) break;
    cp += i;
  }
 in->string = cp;
 if (buf)
  { i = cp - start;
    buf[i] = '\0';
    for (i--;i>=0;i--) buf[i] = *--cp;
  }
 return(1);
}

__TMPRFSM_rec(_TMPRFSM_inp,_TMPRFSM_state)
FSMarg *_TMPRFSM_inp;
int _TMPRFSM_state;
{
 char *cp = _TMPRFSM_inp->string;

 if (__TMPRFSM_(_TMPRFSM_inp,_TMPRFSM_state))
  { return(1);
  }
 if (_TMPRFSM_lastfail == 0)
  { _TMPRFSM_lastfail = _TMPRFSM_inp->string;
  }
 _TMPRFSM_inp->string = cp;
 return(0);
}

_TMPRFSM_xval(c)
char c;
{
 if (isdigit(c))
  { return(c-'0');
  }
 else if (isupper(c))
  { return((c-'A')+10);
  }
 else
  { return((c-'a')+10);
  }
}

__TMPRFSM_(_TMPRFSM_inp,_TMPRFSM_state)
FSMarg *_TMPRFSM_inp;
int _TMPRFSM_state;
{
 while(1)
  { if (!(_TMPRFSM_inp->flags&FSM_FLAG_PARSE_BLANKS))
     { while (isspace(_TMPRFSM_char))
	{ _TMPRFSM_get;
	}
     }
    _TMPRFSM_lastfail = 0;
    
    switch(_TMPRFSM_state){
/*
 *
 *
 *
 * Machine begins here
 *
 *
 *
 */
				case 1: /* real */
if(1){
					/* $lambda */
					_TMPR_init(0)     ;{
_TMPRFSM_state=2;break;}}
					/* ... -> [next state] */
return(0);break;
				case 2:
if(_TMPRFSM_char=='-'){
					/* '-' */
					_TMPR_negative(_TMPRFSM_char)     ;{
_TMPRFSM_get;
_TMPRFSM_state=3;break;}}
					/* ... -> int_digit */
if(_TMPRFSM_char=='+'){
					/* '+' */
{
_TMPRFSM_get;
_TMPRFSM_state=3;break;}}
					/* ... -> int_digit */
if(1){
					/* $lambda */
{
_TMPRFSM_state=3;break;}}
					/* ... -> int_digit */
return(0);break;
				case 3: /* int_digit */
if(isdigit(_TMPRFSM_char)){
					/* $digit */
					_TMPR_int_digit(_TMPRFSM_char)     ;{
_TMPRFSM_get;
_TMPRFSM_state=4;break;}}
					/* ... -> int_got_digit */
if(_TMPRFSM_char=='.'){
					/* '.' */
{
_TMPRFSM_get;
_TMPRFSM_state=5;break;}}
					/* ... -> fraction */
return(0);break;
				case 4: /* int_got_digit */
if(isdigit(_TMPRFSM_char)){
					/* $digit */
					_TMPR_int_digit(_TMPRFSM_char)     ;{
_TMPRFSM_get;
_TMPRFSM_state=4;break;}}
					/* ... -> int_got_digit */
if(_TMPRFSM_char=='.'){
					/* '.' */
{
_TMPRFSM_get;
_TMPRFSM_state=6;break;}}
					/* ... -> frac_got_digit */
if(1){
					/* $lambda */
{
_TMPRFSM_state=7;break;}}
					/* ... -> exp */
return(0);break;
				case 5: /* fraction */
if(isdigit(_TMPRFSM_char)){
					/* $digit */
					_TMPR_frac_digit(_TMPRFSM_char)     ;{
_TMPRFSM_get;
_TMPRFSM_state=6;break;}}
					/* ... -> frac_got_digit */
return(0);break;
				case 6: /* frac_got_digit */
if(isdigit(_TMPRFSM_char)){
					/* $digit */
					_TMPR_frac_digit(_TMPRFSM_char)     ;{
_TMPRFSM_get;
_TMPRFSM_state=6;break;}}
					/* ... -> frac_got_digit */
if(1){
					/* $lambda */
{
_TMPRFSM_state=7;break;}}
					/* ... -> exp */
return(0);break;
				case 7: /* exp */
if(__TMPRFSM_rec(_TMPRFSM_inp,9)){
					/* !exponent */
{
_TMPRFSM_state=8;break;}}
					/* ... -> [next state] */
if(1){
					/* $lambda */
{
_TMPRFSM_state=8;break;}}
					/* ... -> [next state] */
return(0);break;
				case 8:
if(_TMPRFSM_char=='\0'){
					/* $eos */
					_TMPR_finish_real(0)     ;{
return(1);}}
					/* ... -> $exit */
return(0);break;
				case 9: /* exponent */
if(_TMPRFSM_anyof0[_TMPRFSM_char]){
					/* $anyof real_exp_char */
{
_TMPRFSM_get;
_TMPRFSM_state=10;break;}}
					/* ... -> [next state] */
return(0);break;
				case 10:
if(_TMPRFSM_char=='+'){
					/* '+' */
{
_TMPRFSM_get;
_TMPRFSM_state=11;break;}}
					/* ... -> [next state] */
if(_TMPRFSM_char=='-'){
					/* '-' */
					_TMPR_negate_exp(_TMPRFSM_char)     ;{
_TMPRFSM_get;
_TMPRFSM_state=11;break;}}
					/* ... -> [next state] */
if(1){
					/* $lambda */
{
_TMPRFSM_state=11;break;}}
					/* ... -> [next state] */
return(0);break;
				case 11:
if(isdigit(_TMPRFSM_char)){
					/* $decimal */
long int _TMPRFSM_i=_TMPRFSM_char-'0';
while(isdigit(_TMPRFSM_get))
_TMPRFSM_i=(_TMPRFSM_i*10)+_TMPRFSM_char-'0';
					_TMPR_set_exp(_TMPRFSM_i)     ;{
return(1);}}
					/* ... -> $exit */
return(0);break;
}}}
