#ifndef PARSER_H
#define PARSER_H


/*#define INPUT 1
#define OUTPUT 2
#define AND 3
#define NAND 4
#define OR 5
#define NOR 6
#define XOR 7
#define NOT 8
#define BUFF 9
*/



    const int AND=0;
	const int NAND=1;
	const int OR=2;
	const int NOR=3;
	const int XOR=5;
	const int BUFF=9;
    const int NOT=10;
	const int INPUT=11;
	const int OUTPUT=12;



#include <iostream>
#include <fstream>
#include <string>

#include "stack.h"

using namespace std;

namespace sat_atpg {

class Gate_token
{
	public:
		int kind;
		string name;
		int input_count;
		string *inputs;
		Gate_token ( int _kind,string _name,int _input_count ) :kind ( _kind ),name ( _name ),input_count ( _input_count ) {inputs = new string[_input_count];}
		~Gate_token() {
				delete []inputs;
			      }				
		void output ( ostream &stream )
		{
			stream << name << " = " << kind;
			if (input_count>0)
                           {
				stream   << "(";
			  	for ( int i=0; i<input_count-1; i++ )
					stream << inputs[i] << ",";
				stream << inputs[input_count-1] <<")"; 
			   }
			stream << endl;
		}

};

class Fault_token
{
	public:
		string from;
		string to;
		bool polarity;
		Fault_token ( string _from,string _to, bool _polarity ) :from ( _from ),to ( _to ),polarity ( _polarity ) {}

		void output ( ostream &stream )
		{
			stream << from;
			if ( to!="" )
				stream << "->" << to;
			stream << " ";
			if ( polarity )
				stream << "/1";
			else
				stream << "/0";
			stream << endl;
		}
};



class Parser
{
	private:
		My_Queue<Gate_token> inputs,outputs,gates;
		My_Queue<Fault_token> faults;
	public:
		Parser()
		{}
		~Parser() {}

		string noSpaces ( string s )
		{
			string r;
			for ( unsigned int i=0; i<s.length(); i++ )
				if ( ! isspace ( s[i] ) )
					r.append ( s.substr ( i,1 ) );
			return r;
		}

		string toLowerCase ( const string& s )
		{
			string t;
			for ( string::const_iterator i = s.begin(); i != s.end(); ++i )
				t += tolower ( *i );
			return t;
		}

		int parse_bench ( istream &f );
		int parse_faults ( istream &f );
		My_Queue<Gate_token>& get_inputs() {return inputs; }
		My_Queue<Gate_token>& get_gates() {return gates; }
		My_Queue<Gate_token>& get_outputs() {return outputs; }
		My_Queue<Fault_token>& get_faults() {return faults; }
};

}
#endif
