%{

#include <stdio.h>

extern int line_nr;
extern char *get_type(char*);

extern char* yytext;
extern void yyerror(char *);

%}


/* TOKENS */

%token GE
%token LE
%token NE
%token EQ
%token AND
%token OR
%token NOT
%token INCR
%token DECR
%token FOR
%token WHILE
%token IF
%token ELSE
%token PRINT
%token INPUT
%token IDENTIFIER
%token INTEGER
%token FLOAT
%token STRING
%token VARIABLE

%union {
   char* str_value;
}

%type <str_value> IDENTIFIER
%type <str_value> INTEGER
%type <str_value> FLOAT
%type <str_value> STRING
%type <str_value> VARIABLE 

/* STARTING RULE */

%start program

%%

/* RULES */

program
	: statement_list
	;
	
statement
	: expression_statement
	| print_statement
	| iteration_statement
	| selection_statement
	;

statement_list
	: statement
	| statement_list statement
	;

block
	: '{' { printf("{"); } statement_list '}' { printf("}"); }
	;

print_statement
	: PRINT STRING ';'   { printf("printf(%s);", $2); free($2); }
	| PRINT VARIABLE ';' 
		{ if( get_type($2) == NULL )
		  {
		     printf("printf(\"%%d\", %s);", make_var($2, "int") );
		  }
		  else if ( strncmp(get_type($2), "float", 5)==0 )
		  {
		    printf("printf(\"%%f\", %s);", $2); 
		  }
		  else if ( strncmp(get_type($2), "char *", 6)==0 )
		  {
		    printf("printf(\"%%s\", %s);", $2); 
		  }
		  else if ( strncmp(get_type($2), "int", 3)==0 )
		  {
		    printf("printf(\"%%d\", %s);", $2); 
		  }
		  
		  free($2); }
	;


iteration_statement
	: FOR '(' { printf("for( "); }
	  expression_statement expression_statement expression
	  ')' { printf(" )"); } block
	| WHILE '(' { printf("while( "); }
	  expression
	  ')' { printf(" )"); } block
	;

selection_statement
	: IF '(' { printf("if( "); } expression ')' { printf(" )"); } 
	  block else_statement
	;

else_statement
	: /* no else */
	| ELSE { printf("else"); } block
	;
	
expression
	: VARIABLE   { printf("%s", make_var($1, "int") ); free($1); }
	| INTEGER    { printf("%s", $1); free($1); }
	| FLOAT      { printf("%s", $1); free($1); }
	| STRING     { printf("%s", $1); free($1); }
	| IDENTIFIER { printf("%s", $1); free($1); }
	| INPUT      { printf("get_input()"); }
	|'(' expression ')'
	| assignment_expression
	| additive_expression
	| relational_expression
	| equality_expression
	;

expression_statement
	: ';'            { printf(";"); }
	| expression ';' { printf(";"); }
	;

assignment_operator
	: '=' { printf("="); }
	;

relational_operator
	: '<' { printf("<");  }
	| '>' { printf(">");  }
	| GE  { printf(">="); }
	| LE  { printf("<="); }
	;

equality_operator
	: EQ { printf("=="); }
	| NE { printf("!="); }
	;

assignment_expression
	: VARIABLE { printf("%s", $1 /*make_var( $1, "int" )*/ );  free($1);  }  
	  assignment_operator
	  expression
	;

relational_expression
	: VARIABLE { printf("%s", make_var( $1, "int") );  free($1); }
	  relational_operator
	  expression
	;

additive_expression
	: VARIABLE { printf("%s", make_var( $1, "int") );  free($1);  }
	  '+'      { printf("+"); }
	  expression
	| VARIABLE { printf("%s", make_var( $1, "int") );  free($1);  }
	  '-'      { printf("-"); }
	  expression
	| INCR { printf("++"); }
	  VARIABLE { printf("%s", make_var( $3, "int") );  free($3);  }
	| VARIABLE { printf("%s", make_var( $1, "int") );  free($1);  }
	  INCR { printf("++"); }
	| DECR { printf("--"); }
	  VARIABLE { printf("%s", make_var( $3, "int") );  free($3);  }
	| VARIABLE { printf("%s", make_var( $1, "int") );  free($1);  }
	  DECR { printf("--"); }

	;

equality_expression
	: VARIABLE { printf("%s", make_var( $1, "int") );  free($1);  }
	  equality_operator
	  expression
	;

%%

#include <string.h>

/* error function */
extern void yyerror(char *s)
{
	fprintf(stderr, "syntax error in line %ld: %s\n", line_nr, yytext);
	remove("./yytemp");
	exit(1);
}



syntax highlighted by Code2HTML, v. 0.9.1