User:Antigng/AF/AFParser

#include <stdio.h>
#include "AFTokenizer.h"
#include "struct.h"

struct _AFToken next_token={T_NONE,};

/* An LL(1) parser. */
#define LL1GetNextToken() \
{\
	if(AFGetNextToken(&next_token))\
	{\
		return 1;\
	}\
}

static int AFParserMatchCondition();
static int AFParserMatchStatement();
/* ArgList -> ε | Statement | ( Statement T_COMMA Arglist ) */
static int AFParserMatchArgList()
{
_match_begin:
	switch(next_token.type)
	{
	case T_KET:
		return 0;
		break;
	case T_SQUARE_KET:
		return 0;
		break;
	default:
		break;
	}
	if(AFParserMatchStatement())
	{
		return 1;
	}
	if(next_token.type!=T_COMMA)
	{
		return 0;
	}
	LL1GetNextToken();
	goto _match_begin;
}
/* Array -> T_SQUARE_BRA Arglist T_SQUARE_KET */
static int AFParserMatchArray()
{
	if(next_token.type!=T_SQUARE_BRA)
	{
		return 1;
	}
	LL1GetNextToken();
	if(AFParserMatchArgList())
	{
		return 1;
	}
	if(next_token.type!=T_SQUARE_KET)
	{
		return 1;
	}
	LL1GetNextToken();
	return 0;
}
/* FuncCall -> T_BRA Arglist T_KET */
static int AFParserMatchFuncCall(struct _str func)
{
	if(next_token.type==T_BRA)
	{
		LL1GetNextToken();
		if(AFParserMatchArgList())
		{
			return 1;
		}
		if(next_token.type!=T_KET)
		{
			return 1;
		}
		LL1GetNextToken();
	}
	return 0;
}
/* Atomic -> ( T_ID ) | ( T_ID FuncCall ) | ( T_STRING ) | ( T_INT ) | ( T_FLOAT ) | ( K_true | K_false | K_null ) | ( Array ) */
static int AFParserMatchAtomic()
{
	switch(next_token.type)
	{
	case T_ID:
		LL1GetNextToken();
		if(AFParserMatchFuncCall(next_token.value.s))
		{
			return 1;
		}
		return 0;
		break;
	case T_STRING:
		break;
	case T_INT:
		break;
	case T_FLOAT:
		break;
	case T_KEYWORD:
		switch(next_token.value.key)
		{
		case K_true:
			break;
		case K_false:
			break;
		case K_null:
			break;
		default:
			return 1;
		}
		break;
	case T_SQUARE_BRA:
		if(AFParserMatchArray())
		{
			return 1;
		}
		return 0;
		break;
	default:
		return 1;
	}
	LL1GetNextToken();
	return 0;
}
/* Braced -> Atomic | ( T_BRA Statement T_KET ) */
static int AFParserMatchBraced()
{
	if(next_token.type==T_BRA)
	{
		LL1GetNextToken();
		if(AFParserMatchStatement())
		{
			return 1;
		}
		if(next_token.type!=T_KET)
		{
			return 1;
		}
		LL1GetNextToken();
		return 0;
	}
	return AFParserMatchAtomic();
}
/* Deref -> ε | ( T_SQUARE_BRA Statement T_SQUARE_KET Deref ) */
static int AFParserMatchDeref()
{
_match_begin:
	if(next_token.type==T_SQUARE_BRA)
	{
		LL1GetNextToken();
		if(AFParserMatchStatement())
		{
			return 1;
		}
		if(next_token.type!=T_SQUARE_KET)
		{
			return 1;
		}
		LL1GetNextToken();
		goto _match_begin;
	}
	return 0;
}
/* Unit -> Braced Deref */
static int AFParserMatchUnit()
{
	if(AFParserMatchBraced())
	{
		return 1;
	}
	return AFParserMatchDeref();
}
/* Unarys -> ( ε | O_PLUS | O_MINUS ) Unit */
static int AFParserMatchUnarys()
{
	if(next_token.type==T_OP)
	{
		switch(next_token.value.op)
		{
		case O_PLUS:
		case O_MINUS:
			LL1GetNextToken();
			break;
		default:
			break;
		}
	}
	return AFParserMatchUnit();
}
/* SpecialWords -> ( ε | K_like | K_in | K_contains | K_rlike | K_irlike ) Unarys */
static int AFParserMatchSpecialWords()
{
	if(next_token.type==T_KEYWORD)
	{
		switch(next_token.value.key)
		{
		case K_like:
		case K_in:
		case K_contains:
		case K_rlike:
		case K_irlike:
			LL1GetNextToken();
			return AFParserMatchUnarys();
			break;
		default:
			break;
		}
	}
	return 0;
}
/* Results -> Unarys SpecialWords */
static int AFParserMatchResults()
{
	if(AFParserMatchUnarys())
	{
		return 1;
	}
	return AFParserMatchSpecialWords();
}
/* BoolInverted -> ( ε | O_NOT ) Results */
static int AFParserMatchBoolInverted()
{
	if(next_token.type==T_OP)
	{
		if(next_token.value.op==O_NOT)
		{
			LL1GetNextToken();
		}
	}
	return AFParserMatchResults();
}
/* PowerTail -> ε | ( O_EXP BoolInverted PowerTail ) */
static int AFParserMatchPowerTail()
{
_match_begin:
	if(next_token.type==T_OP)
	{
		if(next_token.value.op==O_EXP)
		{
			LL1GetNextToken();
			if(AFParserMatchBoolInverted())
			{
				return 1;
			}
			goto _match_begin;
		}
	}
	return 0;
}
/* Power -> BoolInverted PowerTail */
static int AFParserMatchPower()
{
	if(AFParserMatchBoolInverted())
	{
		return 1;
	}
	return AFParserMatchPowerTail();
}
/* Factor -> ε | ( ( O_MUL | O_DIV | O_REM ) Power Factor ) */
static int AFParserMatchFactor()
{
_match_begin:
	if(next_token.type==T_OP)
	{
		switch(next_token.value.op)
		{
		case O_MUL:
		case O_DIV:
		case O_REM:
			LL1GetNextToken();
			if(AFParserMatchPower())
			{
				return 1;
			}
			goto _match_begin;
			break;
		default:
			break;
		}
	}
	return 0;
}
/* Term -> Power Factor */
static int AFParserMatchTerm()
{
	if(AFParserMatchPower())
	{
		return 1;
	}
	return AFParserMatchFactor();
}
/* ArthTail -> ε | ( ( O_PLUS | O_MINUS ) Term ArthTail ) */
static int AFParserMatchArthTail()
{
_match_begin:
	if(next_token.type==T_OP)
	{
		switch(next_token.value.op)
		{
		case O_PLUS:
		case O_MINUS:
			LL1GetNextToken();
			if(AFParserMatchTerm())
			{
				return 1;
			}
			goto _match_begin;
			break;
		default:
			break;
		}
	}
	return 0;
}
/* Arth -> Term ArthTail */
static int AFParserMatchArth()
{
	if(AFParserMatchTerm())
	{
		return 1;
	}
	return AFParserMatchArthTail();
}
/* CompTail -> ε | ( ( O_INEQ | O_SINEQ | O_L | O_LE | O_G | O_GE | O_EQ | O_SEQ ) Arth CompTail ) */
static int AFParserMatchCompTail()
{
_match_begin:
	if(next_token.type==T_OP)
	{
		switch(next_token.value.op)
		{
		case O_INEQ:
		case O_SINEQ:
		case O_L:
		case O_LE:
		case O_G:
		case O_GE:
		case O_EQ:
		case O_SEQ:
			LL1GetNextToken();
			if(AFParserMatchArth())
			{
				return 1;
			}
			goto _match_begin;
			break;
		default:
			break;
		}
	}
	return 0;
}
/* Comparation -> Arth CompTail */
static int AFParserMatchComparation()
{
	if(AFParserMatchArth())
	{
		return 1;
	}
	return AFParserMatchCompTail();
}
/* BoolOpTail -> ε | ( ( O_AND | O_OR | O_XOR ) Term BoolOpTail ) */
static int AFParserMatchBoolOpTail()
{
_match_begin:
	if(next_token.type==T_OP)
	{
		switch(next_token.value.op)
		{
		case O_AND:
		case O_OR:
		case O_XOR:
			LL1GetNextToken();
			if(AFParserMatchComparation())
			{
				return 1;
			}
			goto _match_begin;
			break;
		default:
			break;
		}
	}
	return 0;
}
/* BoolOp -> Comparation BoolOpTail */
static int AFParserMatchBoolOp()
{
	if(AFParserMatchComparation())
	{
		return 1;
	}
	return AFParserMatchBoolOpTail();
}
/* Ternary -> ε | ( O_TER_Q Condition O_TER_S Condition ) */
static int AFParserMatchTernary()
{
	if((next_token.type==T_OP)&&(next_token.value.op==O_TER_Q))
	{
		LL1GetNextToken();
		if(AFParserMatchCondition())
		{
			return 1;
		}
		if((next_token.type!=T_OP)||(next_token.value.op!=O_TER_S))
		{
			return 1;
		}
		LL1GetNextToken();
		return AFParserMatchCondition();
	}
	return 0;
}
/* NonIfStruct -> BoolOp Ternary */
static int AFParserMatchNonIfStruct()
{
	if(AFParserMatchBoolOp())
	{
		return 1;
	}
	return AFParserMatchTernary();
}
/* IfStruct -> K_if Condition K_else Condition K_then Condition K_end */
static int AFParserMatchIfStruct()
{
	if((next_token.type!=T_KEYWORD)||(next_token.value.key!=K_if))
	{
		return 1;
	}
	LL1GetNextToken();
	if(AFParserMatchCondition())
	{
		return 1;
	}
	if((next_token.type!=T_KEYWORD)||(next_token.value.key!=K_then))
	{
		return 1;
	}
	LL1GetNextToken();
	if(AFParserMatchCondition())
	{
		return 1;
	}
	if((next_token.type!=T_KEYWORD)||(next_token.value.key!=K_else))
	{
		return 1;
	}
	LL1GetNextToken();
	if(AFParserMatchCondition())
	{
		return 1;
	}
	if((next_token.type!=T_KEYWORD)||(next_token.value.key!=K_end))
	{
		return 1;
	}
	LL1GetNextToken();
	return 0;
}
/* Condition -> IfStruct | NonIfStruct */
static int AFParserMatchCondition()
{
	if((next_token.type==T_KEYWORD)&&(next_token.value.key==K_if))
	{
		return AFParserMatchIfStruct();
	}
	return AFParserMatchNonIfStruct();
}
/* Factoring out the left common factor. */
static int AFParserMatchIdSpecialTreatment()
{
	switch(next_token.type)
	{
	case T_OP:
		if(next_token.value.op==O_SET)
		{
			LL1GetNextToken();
			return AFParserMatchStatement();
		}
		break;
	case T_SQUARE_BRA:
		if(AFParserMatchDeref())
		{
			return 1;
		}
		if(next_token.value.op==O_SET)
		{
			LL1GetNextToken();
			return AFParserMatchStatement();
		}
		break;
	default:
		if(AFParserMatchFuncCall(next_token.value.s))
		{
			return 1;
		}
		if(AFParserMatchDeref())
		{
			return 1;
		}
		break;
	}
	if(AFParserMatchSpecialWords())
	{
		return 1;
	}
	if(AFParserMatchPowerTail())
	{
		return 1;
	}
	if(AFParserMatchFactor())
	{
		return 1;
	}
	if(AFParserMatchArthTail())
	{
		return 1;
	}
	if(AFParserMatchCompTail())
	{
		return 1;
	}
	if(AFParserMatchBoolOpTail())
	{
		return 1;
	}
	if(AFParserMatchTernary())
	{
		return 1;
	}
	return 0;
}
/* SingleStatement -> ε | IdSpecialTreatment | Condition */
static int AFParserMatchSingleStatement()
{
	switch(next_token.type)
	{
	case T_NONE:
		return 0;
		break;
	case T_ID:
		LL1GetNextToken();
		return AFParserMatchIdSpecialTreatment();
	case T_KET:
		return 0;
	case T_SQUARE_KET:
		return 0;
	case T_STATEMENT_SEPARATOR:
		return 0;
	default:
		break;
	}
	return AFParserMatchCondition();
}
/* Statement -> SingleStatement | SingleStatement T_STATEMENT_SEPARATOR Statement */
static int AFParserMatchStatement()
{
	do
	{
		if(AFParserMatchSingleStatement())
		{
			return 1;
		}
		if(next_token.type!=T_STATEMENT_SEPARATOR)
		{
			break;
		}
		LL1GetNextToken();
	}while(1);
	return 0;
}
/* Root -> Statement T_NONE */
static int AFParserMatchRoot()
{
	LL1GetNextToken();
	if(AFParserMatchStatement())
	{
		return 1;
	}
	if(next_token.type!=T_NONE)
	{
		return 1;
	}
	return 0;
}
int AFParserTest(const char *source,unsigned int len,int show)
{
	AFTokenizerReset(source,len);
	return AFParserMatchRoot();
}
struct hashlist *AFVars=NULL;
int AFParserIni()
{
	AFVars=hashini();
	return 0;
}