%{
#define yyerror printf
extern char* yytext;
#define YYSTYPE char*
#include <string.h>
%}

%left BAR
%token LOZ DOZ LUZ DUZ SLOVO UPITNIK ZVEZDA CRTICA PLUS
%start poc

%%
poc     :       ri                          {  printf("Neprosireni regularni izraz je :\n%s\n",$1);
                                               free($1);
                                            }

ri 	:	ri BAR riili                {  $$=ili($1,$3);          free($1); free($2); }
     	|	riili                       {  $$=$1; }
     	;

riili 	:	riili riputa                {  $$=puta($1,$2);         free($1); free($2); }
	|	riputa                      {  $$=$1; }
	;

riputa  :	LOZ ri DOZ                  {  $$=zagradi($2);         free($2); }
        |       riputa UPITNIK              {  $$=upitnik($1);         free($1); }  
   	|  	riputa PLUS                 {  $$=plus($1);            free($1); }
        |       riputa ZVEZDA               {  $$=zvezda($1);          free($1); }
   	|  	LUZ slovo CRTICA slovo DUZ  {  $$=klasa($2[0],$4[0]);  free($2); free($4); }
	|  	slovo                       {  $$=$1; }
   	;

slovo   :       SLOVO                       { $$=strdup(yytext); }

%%

char* zagradi(char* s)
{   char* r=(char *)malloc(strlen(s)+3);
    sprintf(r,"(%s)",s);
    return r;
}

char* ili(char* s, char* t)
{   char* r=(char *)malloc(strlen(s)+strlen(t)+2);
    sprintf(r,"%s|%s",s,t);
    return r;
}

char* puta(char* s, char *t)
{   char* r=(char *)malloc(strlen(s)+strlen(t)+1);
    sprintf(r,"%s%s",s,t);
    return r;
}


char* upitnik(char* s)
{   char* r=(char *)malloc(strlen(s)+7);
    sprintf(r,"(%s|eps)",s);
    return r;
}

char* plus(char* s)
{   char* r=(char *)malloc(2*strlen(s)+4);
    sprintf(r,"%s(%s)*",s,s);
    return r;
}

char* zvezda(char* s)
{   char* r=(char *)malloc(strlen(s)+2);
    sprintf(r,"%s*",s);
    return r;
}

char* klasa(char a, char b)
{   char* r;
    char c;
    if (b>=a)
    {   r=(char *)malloc(2*(b-a)+4);
        r[0]='(';
        for (c=a; c<=b; c++)
        {   r[2*(c-a)+1]=c;
            r[2*(c-a)+2]='|';
        }
        r[2*(b-a)+2]=')';
        r[2*(b-a)+3]='\0';
    } 
    else
    {  r=(char *)malloc(1);
       r[0]='\0';
    }
    return r;
}

main()
{ yyparse();
}
