#include "bench_parser.h"
#include "config.h"
#include "err.h"
#include <stdexcept>
#include <string>
#include <sstream>
//---------------------------------------------------------------------------
void BenchParser::run (const std::string& fn) {
    l.init (fn.c_str());
    token=l.NextToken();
    client_->haveDesign ();
    
    inputs();
    outputs();
    assigns();
    l.CheckToken (token,LEX_B_NULL);
    client_->endDesign ();
}
//---------------------------------------------------------------------------
void BenchParser::inputs() {
    while (token == LEX_B_INPUT) { 			// Outputs -> OUTPUT ( IDENT ) Outputs
	token=l.CheckNextToken(LEX_B_LPA);
	token=l.CheckNextToken(LEX_B_IDENT);		// input name
	client_->haveInPort (l.Lex_AStr);
	token=l.CheckNextToken(LEX_B_RPA);
	token=l.NextToken();
    }
}
//---------------------------------------------------------------------------
void BenchParser::outputs() {
    while (token == LEX_B_OUTPUT) {			// Outputs -> OUTPUT ( IDENT ) Outputs
	token=l.CheckNextToken(LEX_B_LPA);
	token=l.CheckNextToken(LEX_B_IDENT);		// output name
	client_->haveOutPort (l.Lex_AStr);
	token=l.CheckNextToken(LEX_B_RPA);
	token=l.NextToken();
    }
}
//---------------------------------------------------------------------------
void BenchParser::assigns()
{
	int f_token;								// function lex symbol
    while (token==LEX_B_IDENT) {				// Assigns -> IDENT ASSIGN Hradlo Assigns
		std::string OutputName = l.Lex_AStr;
		token = l.CheckNextToken(LEX_B_ASSIGN);
		token = f_token = l.CheckNextToken(LexanBench :: isFunc, LEX_B_ANY_FUNC);
	
		list<std::string> listInputNames;       // object #5
		hradlo (&listInputNames);				// set list of inputs
		client_->haveAssign (OutputName, f_token, listInputNames);
    }
}
//---------------------------------------------------------------------------
void BenchParser::hradlo (list<std::string> *listInputNames) {
//    int id=0;
    token=l.CheckNextToken(LEX_B_LPA);
    token=l.NextToken();
    idents(listInputNames);
    if(token==LEX_B_RPA) {
	token=l.NextToken();
    } else {
	throw SyntaxException (TokenReason (l, token, LEX_B_RPA), LexPosition(l));
    }
}
//---------------------------------------------------------------------------
void BenchParser::idents(list<std::string> *listInputNames)
{
   if(token==LEX_B_IDENT) // Idents -> IDENT R_O_Idents
   {
      listInputNames->push_back(l.Lex_AStr);
      token=l.NextToken();
      r_o_idents(listInputNames);
   }
   else
   {
      throw SyntaxException (TokenReason (l, token, LEX_B_IDENT), LexPosition(l));
   }
}
//---------------------------------------------------------------------------
void BenchParser::r_o_idents(list<std::string> *listInputNames)
{
   if(token!=LEX_B_COMMA) return; 	// R_O_Idents -> , IDENT R_O_Idents
   token=l.CheckNextToken(LEX_B_IDENT);
   listInputNames->push_back(l.Lex_AStr);
   token=l.NextToken();
   r_o_idents(listInputNames);
}
//---------------------------------------------------------------------------
void BenchParserClient :: haveDesign (void) {}
void BenchParserClient :: endDesign (void) {}
void BenchParserClient :: haveInPort  (const std::string& portName) {}
void BenchParserClient :: haveOutPort (const std::string& portName) {}
void BenchParserClient :: haveAssign (const std::string& OutputName, 
			     int function, 
			     const list<std::string> listInputNames) {}
BenchParserClient :: ~BenchParserClient () { }
