User:Antigng/AF/AFParser
< User:Antigng | AF
#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;
}