User:Antigng-bot/regex/regexBackEnd

维基百科,自由的百科全书
#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;
}