%glr-parser
%token ID

%{
#include <ctype.h>
#include <stdio.h>

static const char *input = "(x)+(y)+z";

#define YYSTYPE char *

static void yyerror (const char *s)
{
  printf ("%s\n", s);
}

static YYSTYPE stmtMerge (YYSTYPE a, YYSTYPE b)
{
  char *s;
  asprintf (&s, "(ALT %s %s)", a, b);
  return s;
}

static int yylex ();
%}

%%

main: add_expr { puts ($1); };

add_expr: mult_expr              %merge <stmtMerge>
        | add_expr '+' mult_expr %merge <stmtMerge>
                                 { asprintf (&$$, "(+ %s %s)", $1, $3); }
        | add_expr '-' mult_expr { asprintf (&$$, "(- %s %s)", $1, $3); }
        ;

mult_expr: factor
         | mult_expr '*' factor  { asprintf (&$$, "(* %s %s)", $1, $3); }
         | mult_expr '/' factor  { asprintf (&$$, "(/ %s %s)", $1, $3); }
         ;

factor: '(' add_expr ')'         { asprintf (&$$, "(par %s)", $2); }
      | '(' ID ')' factor        { asprintf (&$$, "(cast %s %s)", $2, $4); }
      | '+' factor               { asprintf (&$$, "(+ %s)", $2); }
      | '-' factor               { asprintf (&$$, "(- %s)", $2); }
      | ID
      ;
%%

static int yylex ()
{
  char c = *input ? *input++ : 0;
  asprintf (&yylval, "%c", c);
  return isalnum (c) ? ID : c;
}

int main ()
{
  printf ("%i\n", yyparse ());
}
