//---------------------------------------------------------------------------
#ifdef _BCPLUSPLUS_
#pragma hdrstop
#endif
#include <stdexcept>
#include <ctype.h>
#include "lexan_edif.h"
#include <math.h>
#include <iostream>	//debug
#include "config.h"
//---------------------------------------------------------------------------
LexanEdif::LexanEdif(const char *input_file):
    Lexan (input_file)
{
   rowcount=1;		// redefining Lexan's value!
   kw_init();
}
//---------------------------------------------------------------------------
void LexanEdif::init(const char *n)
{
   Lexan::init (n);
   if (keywords.size() == 0)  kw_init();
   rowcount=1;
}
//---------------------------------------------------------------------------
int LexanEdif::NextToken() {
    if(!qtoken.empty()) {
	int k=qtoken.front();
	qtoken.pop();
	return k;
    }
    int Exp=0,ExpSign=1;
    double DmsPos=0.1;
    int state=0;
    char c;
    F>>noskipws;
    while(true) {
	F>>c;
	if(c=='\n') { 
	    rowcount++; 
	    if (rowcount % 1000 == 0)  cerr << ".." << rowcount;
	    if (rowcount % 10000 == 0) cerr << endl; }
	switch(state) {
	    // ------------------ symbol start -------------------------
	    case 0:
		if (!F) { cerr << endl; return LEX_E_NULL; }
		if (isspace (c)) break;
		if (c=='(') return LEX_E_LPA;
		if (c==')') return LEX_E_RPA;
		if (c=='\"') {
		    state=13;
		    Lex_AStr = "";
		    break;
		}
		if ( isdigit (c)) {
		    state=5;
		    Lex_AInt=c-'0';
		    Lex_AReal=c-'0';
		    break;
		}
		if (c=='#') {
		    state=1;
		    break;
		}
		if (isalpha (c) || c=='_' || c=='&') {
		    state=14;
		    Lex_AStr=c;
		    break;
		}
		return LEX_E_ERROR;
		
	 // ------------------- comment ---------------------------------	
         case 1:
//            if(!F) return LEX_E_ERROR;
             if(c=='\n') state=0;
             break;
	 // ------------------- number ---------------------------------    
         case 5:
             if (isdigit(c)) {
		 Lex_AInt*=10;
		 Lex_AReal*=10;
		 Lex_AInt+=c-'0';
		 Lex_AReal+=c-'0';
		 break;
            }
            if (c=='.') {
                state=6;
                break;
            }
            if (c=='e' || c=='E') {
                state=7;
                break;
            }
            if(c!='\n') F.unget();
            return LEX_E_INTEGERTOKEN;
	 // ------------------ frac part of number ---------------------    
         case 6:
            if (isdigit (c)) {
               Lex_AReal+=DmsPos*(c-'0');
               DmsPos*=.1;
               break;
            }
            if (c=='e' || c=='E') {
                state=7;
                break;
            }
            if (c!='\n') F.unget();
            return LEX_E_REALTOKEN;
	 // ------------------ exponent sign ---------------------------   
         case 7:
            state=8;
            if (c=='+' || c=='-') {
                ExpSign=(c=='-')?-1:1;
                break;
            }
	 // ------------------ exponent start -------------------------
         case 8:
	     if (isdigit (c)) {
 		 state=9;
 		 Exp*=10;
		 Exp+=c-'0';
		 break;
	     }
	     return LEX_E_ERROR;
	 // ------------------ exponent ------------------------------    
         case 9:
            if (isdigit(c)) {
                Exp*=10;
                Exp+=c-'0';
                break;
	    }
            if (c!='\n') F.unget();
            Lex_AReal*=pow(10.0,Exp*ExpSign);
            return LEX_E_REALTOKEN;
	 // ----------------- string --------------------------------   
         case 13:
             if(c=='\"') return LEX_E_STRINGTOKEN;
             Lex_AStr += c;
             break;
	 // ----------------- ident --------------------------------
         case 14:
            if (isalpha(c) || isdigit(c) || c=='_' || c=='&') {
                Lex_AStr+=c;
                break;
	    }
            if(c!='\n') F.unget();
	    // -------------- keyword decode 
            for(list<pair<int,std::string> >::iterator 
		i=keywords.begin();
		i!=keywords.end();
		i++) {
		std::string s1 =i->second;
		std::string s2 =Lex_AStr;
		if(!stricmp(i->second.c_str(),Lex_AStr.c_str())) return i->first;
            }
            return LEX_E_IDENT;
      }
   }  //end while
}
// ------------------------------------------------------------------
int LexanEdif::LookAhead()
{
   int k=NextToken();
   qtoken.push(k);
   return k;
}
// ------------------------------------------------------------------
void LexanEdif::kw_init()
{
   keywords.clear();
   keywords.push_back(pair<int,std::string>(LEX_E_EDIF,"edif"));
   keywords.push_back(pair<int,std::string>(LEX_E_NAME,"name"));
   keywords.push_back(pair<int,std::string>(LEX_E_RENAME,"rename"));
   keywords.push_back(pair<int,std::string>(LEX_E_STATUS,"status"));
   keywords.push_back(pair<int,std::string>(LEX_E_EDIFVERSION,"edifVersion"));
   keywords.push_back(pair<int,std::string>(LEX_E_EDIFLEVEL,"edifLevel"));
   keywords.push_back(pair<int,std::string>(LEX_E_KEYWORDMAP,"keywordMap"));
   keywords.push_back(pair<int,std::string>(LEX_E_KEYWORDLEVEL,"keywordLevel"));
   keywords.push_back(pair<int,std::string>(LEX_E_WRITTEN,"written"));
   keywords.push_back(pair<int,std::string>(LEX_E_TIMESTAMP,"timestamp"));
   keywords.push_back(pair<int,std::string>(LEX_E_AUTHOR,"author"));
   keywords.push_back(pair<int,std::string>(LEX_E_PROGRAM,"program"));
   keywords.push_back(pair<int,std::string>(LEX_E_DATAORIGIN,"dataOrigin"));
   keywords.push_back(pair<int,std::string>(LEX_E_VERSION,"version"));
   keywords.push_back(pair<int,std::string>(LEX_E_LIBRARY,"library"));
   keywords.push_back(pair<int,std::string>(LEX_E_TECHNOLOGY,"technology"));
   keywords.push_back(pair<int,std::string>(LEX_E_NUMBERDEFINITION,"numberDefinition"));
   keywords.push_back(pair<int,std::string>(LEX_E_CELL,"cell"));
   keywords.push_back(pair<int,std::string>(LEX_E_CELLTYPE,"cellType"));
   keywords.push_back(pair<int,std::string>(LEX_E_TIE,"tie"));
   keywords.push_back(pair<int,std::string>(LEX_E_RIPPER,"ripper"));
   keywords.push_back(pair<int,std::string>(LEX_E_GENERIC,"generic"));
   keywords.push_back(pair<int,std::string>(LEX_E_VIEW,"view"));
   keywords.push_back(pair<int,std::string>(LEX_E_NETLIST,"netList"));
   keywords.push_back(pair<int,std::string>(LEX_E_VIEWTYPE,"viewType"));
   keywords.push_back(pair<int,std::string>(LEX_E_INTERFACE,"interface"));
   keywords.push_back(pair<int,std::string>(LEX_E_PORT,"port"));
   keywords.push_back(pair<int,std::string>(LEX_E_ARRAY,"array"));
   keywords.push_back(pair<int,std::string>(LEX_E_CONTENTS,"contents"));
   keywords.push_back(pair<int,std::string>(LEX_E_INSTANCE,"instance"));
   keywords.push_back(pair<int,std::string>(LEX_E_INSTANCEREF,"instanceRef"));
   keywords.push_back(pair<int,std::string>(LEX_E_VIEWREF,"viewRef"));
   keywords.push_back(pair<int,std::string>(LEX_E_CELLREF,"cellRef"));
   keywords.push_back(pair<int,std::string>(LEX_E_LIBRARYREF,"libraryRef"));
   keywords.push_back(pair<int,std::string>(LEX_E_NET,"net"));
   keywords.push_back(pair<int,std::string>(LEX_E_JOINED,"joined"));
   keywords.push_back(pair<int,std::string>(LEX_E_PORTREF,"portRef"));
   keywords.push_back(pair<int,std::string>(LEX_E_MEMBER,"member"));
   keywords.push_back(pair<int,std::string>(LEX_E_DESIGN,"design"));
   keywords.push_back(pair<int,std::string>(LEX_E_PROPERTY,"property"));
   keywords.push_back(pair<int,std::string>(LEX_E_STRING,"string"));
   keywords.push_back(pair<int,std::string>(LEX_E_OWNER,"owner"));
   keywords.push_back(pair<int,std::string>(LEX_E_INPUT,"INPUT"));
   keywords.push_back(pair<int,std::string>(LEX_E_OUTPUT,"OUTPUT"));
   keywords.push_back(pair<int,std::string>(LEX_E_INOUT,"INOUT"));
   keywords.push_back(pair<int,std::string>(LEX_E_DIRECTION,"direction"));
   keywords.push_back(pair<int,std::string>(LEX_E_VIEWLIST,"viewList"));
   keywords.push_back(pair<int,std::string>(LEX_E_EXTERNAL,"external"));
   keywords.push_back(pair<int,std::string>(LEX_E_SIMULATIONINFO,"simulationInfo"));
   keywords.push_back(pair<int,std::string>(LEX_E_LOGICVALUE,"logicValue"));
   keywords.push_back(pair<int,std::string>(LEX_E_BOOLEANMAP,"booleanMap"));
   keywords.push_back(pair<int,std::string>(LEX_E_BOOLEANVALUE,"booleanValue"));
   keywords.push_back(pair<int,std::string>(LEX_E_BOOLEAN,"boolean"));
   keywords.push_back(pair<int,std::string>(LEX_E_INTEGER,"integer"));
   keywords.push_back(pair<int,std::string>(LEX_E_FALSE,"false"));
   keywords.push_back(pair<int,std::string>(LEX_E_TRUE,"true"));
   symbols.clear();
   symbols.push_back(pair<int,std::string>(LEX_E_NULL, "(eof)"));
   symbols.push_back(pair<int,std::string>(LEX_E_ERROR,"(unknown)"));
   symbols.push_back(pair<int,std::string>(LEX_E_INTEGERTOKEN,"int number"));
   symbols.push_back(pair<int,std::string>(LEX_E_REALTOKEN,"real number"));
   symbols.push_back(pair<int,std::string>(LEX_E_LPA,"("));
   symbols.push_back(pair<int,std::string>(LEX_E_RPA,")"));
   symbols.push_back(pair<int,std::string>(LEX_E_IDENT,"identifier"));
}
//---------------------------------------------------------------------------
