/* $Id: grammar.lemon 21321 2007-04-03 19:08:00Z lego $ */

%include {
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "dfilter-int.h"
#include "syntax-tree.h"
#include "sttype-range.h"
#include "sttype-test.h"
#include "sttype-function.h"
#include "drange.h"

#include "grammar.h"

#ifdef _WIN32
#pragma warning(disable:4671)
#endif
	
/* End of C code */
}

/* Parser Information */
%name		Dfilter
%token_prefix	TOKEN_
%extra_argument	{dfwork_t *dfw}

/* Terminal and Non-Terminal types and destructors */
%token_type			{stnode_t*}
%token_destructor		{stnode_free($$);}

%type		sentence	{stnode_t*}


%type		expr		{stnode_t*}
%destructor	expr		{stnode_free($$);}

%type		entity		{stnode_t*}
%destructor	entity		{stnode_free($$);}

%type		relation_test	{stnode_t*}
%destructor	relation_test	{stnode_free($$);}

%type		logical_test	{stnode_t*}
%destructor	logical_test	{stnode_free($$);}

%type		rel_op2		{test_op_t}

%type		range		{stnode_t*}
%destructor	range		{stnode_free($$);}

%type		drnode		{drange_node*}
%destructor	drnode		{drange_node_free($$);}

%type		drnode_list	{GSList*}
%destructor	drnode_list	{drange_node_free_list($$);}

%type		funcparams	{GSList*}
%destructor	funcparams	{st_funcparams_free($$);}

/* This is called as soon as a syntax error happens. After that, 
any "error" symbols are shifted, if possible. */
%syntax_error {

	header_field_info	*hfinfo;

	if (!TOKEN) {
		dfilter_fail("Unexpected end of filter string.");
		return;
	}

	switch(stnode_type_id(TOKEN)) {
	        case STTYPE_UNINITIALIZED:
			dfilter_fail("Syntax error.");
			break;
		case STTYPE_TEST:
			dfilter_fail("Syntax error, TEST.");
			break;
		case STTYPE_STRING:
			dfilter_fail("The string \"%s\" was unexpected in this context.",
				stnode_data(TOKEN));
			break;
		case STTYPE_UNPARSED:
			dfilter_fail("\"%s\" was unexpected in this context.",
				stnode_data(TOKEN));
			break;
		case STTYPE_INTEGER:
			dfilter_fail("The integer %d was unexpected in this context.",
				stnode_value(TOKEN));
			break;
		case STTYPE_FIELD:
			hfinfo = stnode_data(TOKEN);
			dfilter_fail("Syntax error near \"%s\".", hfinfo->abbrev);
			break;
		case STTYPE_FUNCTION:
			dfilter_fail("The function s was unexpected in this context.");
			break;

		/* These aren't handed to use as terminal tokens from
		   the scanner, so was can assert that we'll never
		   see them here. */
		case STTYPE_NUM_TYPES:
		case STTYPE_RANGE:
		case STTYPE_FVALUE:
			g_assert_not_reached();
			break;
	}
}

/* When a parse fails, mark an error. This occurs after
the above syntax_error code and after the parser fails to
use error recovery, shifting an "error" symbol and successfully
shifting 3 more symbols. */
%parse_failure {
	dfw->syntax_error = TRUE;
}

/* ----------------- The grammar -------------- */

/* Associativity */
%left TEST_AND.
%left TEST_OR.
%nonassoc TEST_EQ TEST_NE TEST_LT TEST_LE TEST_GT TEST_GE TEST_CONTAINS TEST_MATCHES TEST_BITWISE_AND.
%right TEST_NOT.

/* Top-level targets */
sentence ::= expr(X).  		{ dfw->st_root = X; }
sentence ::= .  		{ dfw->st_root = NULL; }

expr(X) ::= relation_test(R).	{ X = R; }
expr(X) ::= logical_test(L).	{ X = L; }


/* Logical tests */
logical_test(T) ::= expr(E) TEST_AND expr(F).
{
	T = stnode_new(STTYPE_TEST, NULL);
	sttype_test_set2(T, TEST_OP_AND, E, F);
}

logical_test(T) ::= expr(E) TEST_OR expr(F).
{
	T = stnode_new(STTYPE_TEST, NULL);
	sttype_test_set2(T, TEST_OP_OR, E, F);
}

logical_test(T) ::= TEST_NOT expr(E).
{
	T = stnode_new(STTYPE_TEST, NULL);
	sttype_test_set1(T, TEST_OP_NOT, E);
}

logical_test(T) ::= entity(E).
{
	T = stnode_new(STTYPE_TEST, NULL);
	sttype_test_set1(T, TEST_OP_EXISTS, E);
}



/* Entities, or things that can be compared/tested/checked */
entity(E) ::= FIELD(F).		{ E = F; }
entity(E) ::= STRING(S).	{ E = S; }
entity(E) ::= UNPARSED(U).	{ E = U; }
entity(E) ::= range(R).		{ E = R; }


/* Ranges */
range(R) ::= FIELD(F) LBRACKET drnode_list(L) RBRACKET.
{
	R = stnode_new(STTYPE_RANGE, NULL);
	sttype_range_set(R, F, L);

	/* Delete the list, but not the drange_nodes that
	 * the list contains. */
	g_slist_free(L);
}

drnode_list(L) ::= drnode(D).
{
	L = g_slist_append(NULL, D);
}

drnode_list(L) ::= drnode_list(P) COMMA drnode(D).
{
	L = g_slist_append(P, D);
}

/* x:y is offset:length */
drnode(D) ::= INTEGER(X) COLON INTEGER(Y).
{
	D = drange_node_new();
	drange_node_set_start_offset(D, stnode_value(X));
	drange_node_set_length(D, stnode_value(Y));
	
	stnode_free(X);
	stnode_free(Y);
}

/* x-y == offset:offset */
drnode(D) ::= INTEGER(X) HYPHEN INTEGER(Y).
{
	D = drange_node_new();
	drange_node_set_start_offset(D, stnode_value(X));
	drange_node_set_end_offset(D, stnode_value(Y));
	
	stnode_free(X);
	stnode_free(Y);
}


/* :y == from start to offset */
drnode(D) ::= COLON INTEGER(Y).
{
	D = drange_node_new();
	drange_node_set_start_offset(D, 0);
	drange_node_set_length(D, stnode_value(Y));

	stnode_free(Y);
}

/* x: from offset to end */
drnode(D) ::= INTEGER(X) COLON.
{
	D = drange_node_new();
	drange_node_set_start_offset(D, stnode_value(X));
	drange_node_set_to_the_end(D);

	stnode_free(X);
}

/* x == x:1 */
drnode(D) ::= INTEGER(X).
{
	D = drange_node_new();
	drange_node_set_start_offset(D, stnode_value(X));
	drange_node_set_length(D, 1);

	stnode_free(X);
}



/* Relational tests */
relation_test(T) ::= entity(E) rel_op2(O) entity(F).
{
	T = stnode_new(STTYPE_TEST, NULL);
	sttype_test_set2(T, O, E, F);
}

rel_op2(O) ::= TEST_EQ.  { O = TEST_OP_EQ; }
rel_op2(O) ::= TEST_NE.  { O = TEST_OP_NE; }
rel_op2(O) ::= TEST_GT.  { O = TEST_OP_GT; }
rel_op2(O) ::= TEST_GE.  { O = TEST_OP_GE; }
rel_op2(O) ::= TEST_LT.  { O = TEST_OP_LT; }
rel_op2(O) ::= TEST_LE.  { O = TEST_OP_LE; }
rel_op2(O) ::= TEST_BITWISE_AND.  { O = TEST_OP_BITWISE_AND; }
rel_op2(O) ::= TEST_CONTAINS.  { O = TEST_OP_CONTAINS; }
rel_op2(O) ::= TEST_MATCHES.  { O = TEST_OP_MATCHES; }


/* Functions */

/* A function can have one or more parameters */
entity(E) ::= FUNCTION(F) LPAREN funcparams(P) RPAREN.
{
    E = F;
	sttype_function_set_params(E, P);
}

/* A function can have zero parameters. */
entity(E) ::= FUNCTION(F) LPAREN RPAREN.
{
    E = F;
}

funcparams(P) ::= entity(E).
{
	P = g_slist_append(NULL, E);
}

funcparams(P) ::= funcparams(L) COMMA entity(E).
{
	P = g_slist_append(L, E);
}


/* Any expression inside parens is simply that expression */
expr(X) ::= LPAREN expr(Y) RPAREN.
{
	X = Y;
}

