%{
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <typeinfo>

#include "i_nj_tree_node.h"
#include "nj_leaf_node.h"
#include "nj_internal_node.h"

using namespace std;

int yylex();
int yyparse();
int yyerror(const char* msg);

NJInternalNode* root = NULL;

%}
//miejsce na tokeny
%token <str> NAME 
%token <num> NUMBER

%type <node> X VERTEX

%union
{
    float num;
    char* str;
    void* node;
}


%%
//miejsce na reguły

S: '(' VERTEX ',' VERTEX ',' VERTEX ')' ';' { 
      NJInternalNode* n2 = NJInternalNode::createNJInternalNode();
      NJInternalNode::setChildNodeLeft (n2, (INJTreeNode*) $2);
      NJInternalNode::setChildNodeRight(n2, (INJTreeNode*) $4);
      NJInternalNode* n1 = NJInternalNode::createNJInternalNode();
      INJTreeNode::setValue(n1, 0);
      INJTreeNode::setValue(n2, 0);
      NJInternalNode::setChildNodeLeft(n1, n2);
      NJInternalNode::setChildNodeRight(n1, (INJTreeNode*) $6);
      root = n1;
      return 1; }
 ;

VERTEX: X ':' NUMBER { 
      $$ = $1; 
      INJTreeNode::setValue((INJTreeNode*) $1, $3);}
 ;

X: '(' VERTEX ',' VERTEX ')' { 
      NJInternalNode* in = NJInternalNode::createNJInternalNode();
      INJTreeNode::setIsLeaf(in, false);
      NJInternalNode::setChildNodeLeft(in, (INJTreeNode*) $2);
      NJInternalNode::setChildNodeRight(in, (INJTreeNode*) $4);
      NJInternalNode::determineLeavesNumber(in);
      $$ = in; }
 | NAME { 
      NJLeafNode* leafn = NJLeafNode::createNJLeafNode();
      NJLeafNode::setSequenceName(leafn, $1);
      INJTreeNode::setIsLeaf(leafn, true);
      $$ = leafn; }
 ;

%%

//int main() {
//   return yyparse();
//}

int yyerror(const char* msg) {
   cout << msg << endl;
}

NJInternalNode* generatedRoot() {
   return root;
}


