#include <stdio.h>
#include "regexFrontEnd.h"
#include "NFARuntime.h"
struct _NFAType *callStack[16384]={0};
int callStackTop=0;
static int callStackPush(struct _NFAType *arg)
{
callStack[callStackTop++]=arg;
return callStackTop>8192;
}
static struct _NFAType *callStackPop()
{
if(callStackTop)
{
callStackTop--;
return callStack[callStackTop];
}
else return NULL;
}
static int callStackIsNull()
{
return callStackTop==0;
}
static int executeNFAUniOperation(unsigned int op)
{
if(callStackIsNull())
{
return 1;
}
else
{
struct _NFAType *arg=callStackPop();
switch(op)
{
case '*':
arg=doKleenStar(arg);
callStackPush(arg);
break;
case '+':
arg=doPositiveClosure(arg);
callStackPush(arg);
break;
case '?':
arg=doQuestion(arg);
callStackPush(arg);
break;
}
}
return 0;
}
static int executeNFABinaryOperation(unsigned int op)
{
if(callStackIsNull())
{
return 1;
}
else
{
struct _NFAType *arg2=callStackPop();
if(callStackIsNull())
{
return 1;
}
else
{
struct _NFAType *arg1=callStackPop();
switch(op)
{
case '|':
arg1=doChoice(arg1,arg2);
callStackPush(arg1);
break;
case '&':
arg1=doConcatenation(arg1,arg2);
callStackPush(arg1);
break;
}
}
}
return 0;
}
static int pushChar(unsigned int ch)
{
struct _NFAType *arg=buildNFAFromChar(ch);
if(callStackPush(arg))
{
return 1;
}
else return 0;
}
static int pushGen(unsigned int gen)
{
struct _NFAType *arg=buildNFAFromGen(gen);
if(callStackPush(arg))
{
return 1;
}
else return 0;
}
static int pushRange(struct _rangeValue range)
{
struct _NFAType *arg=buildNFAFromRange(range);
if(callStackPush(arg))
{
return 1;
}
else return 0;
}
int genNFANodeToQueue(struct _regexToken tok)
{
switch(tok.type)
{
case T_Regex_EOL:
if(callStackTop!=1)
{
return 1;
}
NFARes=callStackPop();
break;
case T_Regex_Ch:
if(pushChar(tok.value.ch)) return 1;
break;
case T_Regex_Gen:
if(pushGen(tok.value.ch)) return 1;
break;
case T_Regex_Range:
if(pushRange(tok.value.range)) return 1;
break;
case T_Regex_Uni_OP:
if(executeNFAUniOperation(tok.value.ch)) return 1;
break;
case T_Regex_Bi_OP:
if(executeNFABinaryOperation(tok.value.ch)) return 1;
break;
default:
fprintf(stderr,"\t\tBackend: Unknown opcode.\n");
return 1;
break;
}
return 0;
}