#include "syntax.h"
//token postion/type
#define TP(POS) tl_tok_type(tl,(POS))
#define TP_EQ(POS,TYPE) (tl_tok_type(tl,(POS)) == TYPE)
#define TP_EQ2(POS,TYPE1,TYPE2) ((tl_tok_type(tl,(POS))==TYPE1)||(tl_tok_type(tl,(POS))==TYPE2))
#define TP_NEQ(POS,TYPE) (tl_tok_type(tl,(POS)) != TYPE)
#define TP_NEQ2(POS,TYPE1,TYPE2) ((tl_tok_type(tl,(POS))!=TYPE1)&&(tl_tok_type(tl,(POS))!=TYPE2))
//check if enought tokens to parse
#define TE(POS) (tl_size(tl) > (POS))
/*****************************************************************************/
ast_root* ast_syntax( token_list *tl )
{
ast_root *ast_tree = NULL;
ast_range *rng = NULL;
tk_pos=0;
ast_tree = atrt_i();
while ( tk_pos < tl_size(tl) )
{
//current - INT|HEX next not RANGE
if (TP_EQ2(tk_pos,TOK_INT,TOK_HEX)
&& TP_NEQ(tk_pos+1,TOK_RANGE))
{
rng = att_range( tl, tk_pos );
if (rng == NULL ) break;
atrt_a_range( &ast_tree, rng, 0 );
// current - INT|HEX next RANGE
} else if ( TP_EQ2(tk_pos,TOK_INT,TOK_HEX)
&& TP_EQ(tk_pos+1,TOK_RANGE) )
{
rng = att_range( tl, tk_pos );
if (rng == NULL ) break;
atrt_a_range( &ast_tree, rng, 0 );
} else
{
printf("ERR:%d\n",tl_tok_type(tl,tk_pos));
printf("Syntax error\n");
break;
}
}
return ast_tree;
}
/*****************************************************************************/
ast_if* att_if( token_list *tl, int pos )
{
//PRINT("IF:pos->%d %d\n",tk_pos,pos);
ast_if *ret = NULL;
ast_expr *expr = NULL;
ast_value *val = NULL;
if ( TP_NEQ(pos,TOK_IF) )
{
printf("not if syntax error\n");
return NULL;
}
// SHOULD BE first LBR (INT|HEX) third RBR
if ((TP_EQ(pos+1,TOK_LBR)) &&
(TP_EQ2(pos+2,TOK_HEX,TOK_INT)) &&
(TP_EQ(pos+3,TOK_RBR)) )
{
expr = att_expr( tl, pos+1 );
pos = tk_pos;
val = att_value( tl, pos );
ret = ati_i();
ati_s_expr( &ret, expr );
ati_s_val( &ret, val );
} else
{
printf("invalid range\n");
return NULL;
}
return ret;
}
/*****************************************************************************/
ast_range* att_range( token_list *tl, int pos )
{
//PRINT("RNG:pos->%d %d\n",tk_pos,pos);
ast_range *ret = NULL;
ast_value *val = NULL;
ast_if *iff = NULL;
if ( TP_NEQ2(pos,TOK_HEX,TOK_INT) )
{
printf("range incorrect syntax\n");
return NULL;
}
//current HEX STR
if ( TP_EQ(pos+1,TOK_STR) )
{
ret = atrn_i();
atrn_s_rng0( &ret, tok2int(tl_get_tok(tl,pos)) );
val = att_value( tl, pos+1 );
if (val==NULL) return NULL;
atrn_s_val( &ret, val );
tk_pos = pos+2;
//current HEX IF ...
} else if ( TP_EQ(pos+1,TOK_IF) )
{
ret = atrn_i();
atrn_s_rng0( &ret, tok2int(tl_get_tok(tl,pos)));
iff = att_if( tl, pos+1 );
if (iff==NULL) return NULL;
atrn_a_if( &ret, iff );
//current HEX RNG HEX
} else if (TP_EQ(pos+1,TOK_RANGE) &&
(TP_EQ2(pos+2,TOK_HEX,TOK_INT)))
{
ret = atrn_i();
atrn_s_rng1( &ret, tok2int(tl_get_tok(tl,pos)), tok2int(tl_get_tok(tl,pos+2)));
if (TP_EQ(pos+3,TOK_STR))
{
val = att_value(tl,pos+3);
if (val==NULL) return NULL;
atrn_s_val( &ret, val );
tk_pos = pos+4;
} else if (TP_EQ(pos+3,TOK_IF))
{
iff = att_if( tl, pos+3 );
if (iff==NULL) return NULL;
atrn_a_if( &ret, iff );
}
} else
{
printf("wrong range syntax TOK=%d\n",tl_tok_type(tl,pos+1));
return NULL;
}
while (TE(tk_pos) && TP_EQ(tk_pos,TOK_IF) && (ret != NULL))
{
//PNL();
pos = tk_pos;
//PRINT("There is more ifs\n");
iff = att_if( tl, pos );
if (iff==NULL) return NULL;
atrn_a_if( &ret, iff );
//PNL();
}
return ret;
}
/*****************************************************************************/
ast_expr* att_expr( token_list *tl, int pos )
{
//PRINT("EXPR:pos->%d %d\n",tk_pos,pos);
ast_expr *ret = NULL;
ast_expr_cmp *cmp = NULL;
// SHOULD BE first LBR (INT|HEX) third RBR
if ( TP_NEQ(pos,TOK_LBR) )
{
printf("Missing ( syntax error\n");
return NULL;
}
if ( TP_NEQ(pos+2,TOK_RBR) )
{
printf("Missing ) syntax error\n");
return NULL;
}
ret = ate_i();
cmp = att_expr_cmp( tl, pos+1 );
if (cmp==NULL) return NULL;
ate_a_cmp( &ret, cmp );
tk_pos += 1;
return ret;
}
/*****************************************************************************/
ast_expr_cmp* att_expr_cmp( token_list *tl, int pos )
{
//PRINT("CMP:pos->%d %d\n",tk_pos,pos);
ast_expr_cmp *ret = NULL;
//current should be one HEX|INT
if (TP_EQ2(pos,TOK_HEX,TOK_INT))
{
ret = atec_i();
atec_s_val( &ret, tok2int(tl_get_tok(tl,pos)));
tk_pos = pos + 1;
} else
{
printf("Expression not INT not HEX\n");
return NULL;
}
return ret;
}
/*****************************************************************************/
ast_expr_bit* att_expr_bit( token_list *tl, int pos )
{
return NULL;
}
/*****************************************************************************/
ast_value* att_value( token_list *tl, int pos )
{
//PRINT("VAL:pos->%d %d\n", tk_pos, pos);
ast_value *val = NULL;
token *tok = NULL;
//current should be one STR
if (TP_NEQ(pos,TOK_STR))
{
printf("value incorrect syntax\n");
return NULL;
}
val = atv_i();
tok = tl_get_tok(tl,pos);
atv_s_note( &val, tok->s, (tok->e)-(tok->s) );
//PRINT("VAL[%.10s]\n",tok->s);
tk_pos = pos + 1;
return val;
}
/*****************************************************************************/
ast_root* atrt_i()
{
ast_root *ret = NULL;
ret = malloc( sizeof(ast_root) );
if (ret == NULL)
{
printf("Cannot alloc ast_root\n");
return NULL;
}
memset( ret, 0, sizeof(ast_root) );
return ret;
}
/*****************************************************************************/
int atrt_a_range( ast_root **rt, ast_range *rng, int idx)
{
//PNL();
(*rt)->range = realloc( (*rt)->range, sizeof(void*)*(*rt)->total_tokens+1 );
(*rt)->range[(*rt)->total_tokens] = rng;
(*rt)->total_tokens += 1;
return 0;
}
/*****************************************************************************/
ast_range* atrn_i()
{
ast_range *ret = NULL;
ret = malloc( sizeof(ast_range) );
if (ret == NULL)
{
printf("Cannot alloc ast_range\n");
return NULL;
}
memset( ret, 0, sizeof(ast_range) );
return ret;
}
/*****************************************************************************/
int atrn_a_if( ast_range **rng, ast_if *iff )
{
//PNL();
(*rng)->iff = realloc( (*rng)->iff, sizeof(void*)*(*rng)->size_iff+1 );
(*rng)->iff[(*rng)->size_iff] = iff;
(*rng)->size_iff += 1;
return 0;
}
/*****************************************************************************/
int atrn_a_val( ast_range **rng, ast_value *val )
{
(*rng)->val = val;
return 0;
}
/*****************************************************************************/
int atrn_s_rng0( ast_range **rng, int value )
{
(*rng)->range_type = 0;
(*rng)->start = value;
(*rng)->end = value;
return 0;
}
/*****************************************************************************/
int atrn_s_rng1( ast_range **rng, unsigned long start, unsigned long end)
{
(*rng)->range_type = 1;
(*rng)->start = start;
(*rng)->end = end;
return 0;
}
/*****************************************************************************/
int atrn_s_val( ast_range **rng, ast_value *val )
{
(*rng)->val = val;
return 0;
}
/*****************************************************************************/
ast_if* ati_i()
{
ast_if *ret = NULL;
ret = malloc( sizeof(ast_if) );
if (ret == NULL)
{
printf("Cannot alloc ast_if\n");
return NULL;
}
memset( ret, 0, sizeof(ast_if) );
return ret;
}
/*****************************************************************************/
int ati_s_expr( ast_if **iff, ast_expr *expr )
{
(*iff)->expr = expr;
return -1;
}
/*****************************************************************************/
int ati_s_val( ast_if **iff, ast_value *val )
{
(*iff)->val = val;
return -1;
}
/*****************************************************************************/
ast_expr* ate_i()
{
ast_expr *ret = NULL;
ret = malloc( sizeof(ast_expr) );
if (ret == NULL)
{
printf("Cannot alloc ast_expr\n");
return NULL;
}
memset( ret, 0, sizeof(ast_expr) );
return ret;
}
/*****************************************************************************/
int ate_a_bit( ast_expr **expr, ast_expr_bit *bit )
{
//PNL();
if ((*expr)->bit == NULL)
{
(*expr)->bit = malloc(sizeof(void *));
(*expr)->bit[0] = bit;
(*expr)->size_bit = 1;
} else
{
(*expr)->bit = realloc( (*expr)->bit, sizeof(void*)*((*expr)->size_bit+1) );
(*expr)->bit[(*expr)->size_bit] = bit;
(*expr)-