%{
#include "packman.h"
#include "y.tab.h"

#define BEGINNING 	200
#define POINT 		201
#define OPEN_HOOK 	202

int lineno = 1, state = 0; 
char oper;
char *buffer;

char buffers[10][256];

u_int8_t buff_i;

char expr[256];
char c_state[256];
char n_state[256];
char header[256];
char field[256];
char bfield[256];
struct phs {
  char pheader[256];
  struct phs *next;
} *phlpaux, *phlp = NULL; /* Previous Header List pointer  */
%}

%%
[ \t]			;               /* ignore white space */
[0-9]+			{ yylval.yyint = atoi(yytext); return NUMBER; }
0x[0-9A-Fa-f]+		{sscanf(yytext,"%x",&yylval.yyint); return NUMBER; }
[0-9]+"us"		{ sscanf(yytext,"%uus",&yylval.yyint);
                	  return U_SEC; }
[0-9]+"ms"		{ sscanf(yytext,"%ums",&yylval.yyint);
                	  return M_SEC; }
\+|\-|\*|\/|\&|\||\^	{ yylval.yychar = yytext[0]; 
                          return OPER; }
action			return ACTION;
all			return ALL;
and			{ state = PM_AND;
			  return PM_AND;}
bpf			return BPF;
but			return BUT;
bye			return TERMINATE;
check			{ state = CHECK;
			  return CHECK;}
command			return COMMAND;
create			{ state = CREATE;
			  return CREATE; }
finish			return FINISH_T;
headers			return HEADERS;
init            	return INIT;
kernel_setup		return KRNL_SETUP;
load			return LOAD;
next			{ state = NEXT; 
			  return NEXT; }
or			return PM_OR;
pack_id			return PACK_ID;
packets			return PACKETS;
play!			return PLAY;
RID			return RID;
send_pack		return SEND_PACKET_T;
shell			return SHELL_T;
show			return SHOW;
state           	return STATE;
states			return STATES;
std_cksum		return STD_CHECKSUM;
store_pack		return STOR_PACK;
recv_pack		return RECV_PACKET_T;
repeat			return REPEAT;
resolve			{ state = RESOLVE;
			  return RESOLVE; }
timeout			return TIMEOUT;
used			return USED;
wait			return WAIT_T;
\=			{ state = EQUAL;
			  return yytext[0]; }
\[			{ state = OPEN_HOOK;
			  return yytext[0]; }
\{              	{ state = OPEN_BRACE;
			  return OPEN_BRACE;
			}
\}              	return CLOSE_BRACE;
\(              	return OPEN_BRACK;
\)              	return CLOSE_BRACK;
\'.\'			{ yylval.yychar = yytext[1];
			  return CHAR;
			}
\".*\"			{ memset(expr,0,256);
			  memcpy(expr,yytext,(strlen(yytext)-1)%256);
			  yylval.yystr = expr + 1;
			  return EXPR;
			}
[0-9a-zA-Z]+		{ switch(state){
			    case BEGINNING:
			    case CREATE:
			    	buffer = c_state;
				break;
			    case OPEN_HOOK:
			    case NEXT:
			    	buffer = n_state;
				break;
			    case OPEN_BRACE:
			        phlpaux = phlp;
				while(phlpaux != NULL){
				  phlpaux = phlpaux->next;
				}
				phlpaux = (struct phs*)malloc(sizeof(struct phs));
				buffer = phlpaux->pheader;
				phlpaux->next = NULL;
				if(phlp == NULL) phlp = phlpaux; 
				break;
		            case EQUAL:
			        buffer = bfield;
			        break;
			    case PM_AND:
			    case RESOLVE:
			    case CHECK:
			        if(phlp != NULL){
				  phlpaux = phlp->next;
				  while(phlp != NULL){
				    free(phlp);
				    phlp = phlpaux;
				    if(phlpaux != NULL) phlpaux = phlpaux->next;
				  }
				}
			    	buffer = header;
				break;
			    case POINT:
			    	buffer = field;
				break;
			    default:
			    	printf("UNREACHABLE!\n");
			  }
 			  memset(buffer,0,256);
			  memcpy(buffer,yytext,(strlen(yytext)+1)%256);
			  yylval.yystr = buffer;
			  return STR;
			}
[\n]			++lineno;
\;			{ state = BEGINNING;
			  return 0;
			}
\>			{ state = CHECK;
			  return yytext[0];
			}
\.			{ state = POINT;
			  return yytext[0];
			}
.			return yytext[0];
%%

yywrap(){
}
