/* SI 413 Fall 2011
 * Lab 6
 * pat.ypp 
 * Parser for pat that just shows the parse tree
 */

%{
#include <cstdlib>
#include <iostream>
using namespace std;

#include "parsetree.hpp"

ParseTree* tree; // This global will be set to the whole parse tree.

int yylex(); 
int yyerror(const char *p) { cerr << "Parse error!" << endl; }

%}

%token SYM FOLD STOP COLON NAME REV LB RB

%%

  /*Note: YYACCEPT is a bison macro that just tells it to quit parsing.*/
S: seq STOP { tree = $1; YYACCEPT; }
|           { tree = NULL; }

seq: seq FOLD catseq {$$ = new ParseTree("seq",$1,$2,$3);}
|    catseq          {$$ = new ParseTree("seq",$1);}

catseq: catseq opseq {$$ = new ParseTree("catseq",$1,$2);}
|       opseq        {$$ = new ParseTree("catseq",$1);}

opseq: opseq COLON NAME {$$ = new ParseTree("opseq",$1,$2,$3);}
|      opseq REV        {$$ = new ParseTree("opseq",$1,$2);}
|      atom             {$$ = new ParseTree("opseq",$1);}

atom: SYM | NAME {$$ = new ParseTree("atom",$1);}
|     LB seq RB  {$$ = new ParseTree("atom",$1,$2,$3)}

%%
int main()
{
  while(true) {
    yyparse();
    if (tree == NULL) break;
    tree->writeDot("pat.dot");
    system("dot -Tpdf pat.dot > pat.pdf");
    system("evince pat.pdf &");
  }
  return 0;
}