%{

extern int yylval;
extern int s_cpLine;

%}

%token CONSTANT
%token EQ NE LE GE LS RS
%token AND_OP OR_OP

%left ','
%right '='
%right '?' ':'
%left OR_OP
%left AND_OP
%left '|' '^'
%left '&'
%binary EQ NE
%binary '<' '>' LE GE
%left LS RS
%left '+' '-'
%left '*' '/' '%'
%right '!' '~' UMINUS

%start start
%%			

start:	e						{ return($1); }
	|	error					{ return(0); }
	;

e:	  e '*' e					{$$ = $1 * $3;}
	| e '/' e					{
		if ($3 == 0) $$ = $1;
		else $$ = $1 / $3;
	}
	| e '%' e					{
		if ($3 == 0) $$ = $1;
		else $$ = $1 % $3;
	}
	| e '+' e					{$$ = $1 + $3;}
	| e '-' e					{$$ = $1 - $3;}
	| e LS e					{$$ = $1 << $3;}
	| e RS e					{$$ = $1 >> $3;}
	| e '<' e					{$$ = $1 < $3;}
	| e '>' e					{$$ = $1 > $3;}
	| e LE e					{$$ = $1 <= $3;}
	| e GE e					{$$ = $1 >= $3;}
	| e EQ e					{$$ = $1 == $3;}
	| e NE e					{$$ = $1 != $3;}
	| e '&' e					{$$ = $1 & $3;}
	| e '^' e					{$$ = $1 ^ $3;}
	| e '|' e					{$$ = $1 | $3;}
	| e AND_OP e				{$$ = $1 && $3;}
	| e OR_OP e					{$$ = $1 || $3;}
	| e '?' e ':' e				{$$ = $1 ? $3 : $5;}
	| e ',' e					{$$ = $3;}
	|  '-' e %prec UMINUS		{$$ = -$2;}
	| '!' e						{$$ = !$2;}
	| '~' e						{$$ = ~$2;}
	| '(' e ')'					{$$ = $2;}
	| CONSTANT					{$$= yylval;}
	;
%%

int yyerror(char *s) {
	int i,c;
	printf("line %d : %s", s_cpLine, s);
	return(0);
}