diff --git a/mg/mglib01.cpp b/mg/mglib01.cpp new file mode 100755 index 000000000..2c45b5877 --- /dev/null +++ b/mg/mglib01.cpp @@ -0,0 +1,602 @@ +#include +#include +#include +#include +#include +#include + +#include "mglib01.h" + + +// ************************** +// classe livelli giacenze +TMag_livelli:: TMag_livelli(const char *tabname) +{ + TTable _tabformato(tabname); + int e; + + e=_tabformato.first(); + for (int i=0; i< MANY_MAG_LEV; i++) { + _enabled[i]=(e==NOERR); + if (_enabled[i]) { + _name[i]=_tabformato.get("S0"); + _code_lenght[i]=atoi(_tabformato.get("I0")); + _picture[i]=_tabformato.get("S1"); + _last_level=i+1; + } else { + _name[i]=""; + _code_lenght[i]=0; + _picture[i]=""; + } + e=_tabformato.next(); + } +} + +const bool TMag_livelli::enabled(int levnum) +{ + if (levnum<=MANY_MAG_LEV && levnum>0) + return(_enabled[levnum-1]); + else + return(FALSE) ; +} + +const int TMag_livelli::code_lenght(int levnum) +{ + if (levnum<=MANY_MAG_LEV && levnum>0) + return(_code_lenght[levnum-1]); + else + return(0) ; +} + +const TString & TMag_livelli::name(int levnum) +{ + if (levnum<=MANY_MAG_LEV && levnum>0) + return(_name[levnum-1]); + else + return(""); +} + +const TString & TMag_livelli::picture(int levnum) +{ + if (levnum<=MANY_MAG_LEV && levnum>0) + return(_picture[levnum-1]); + else + return(""); +} + +void TMag_livelli::pack_grpcode(TString & pc, const TString &codlev, const int levnum) +{ + + int start=0; + for (int i=1; i=pc.len()) + return(""); + else + return(pc.mid(start,levnum == _last_level ? -1 : _code_lenght[levnum-1])); +} + + +// ******************************* +// ******************************* + +// ******************************* +TStateset::TStateset() +{ + empty(); +} + +TStateset & TStateset::empty() +{ _current=0; + for (int i= 0; i< MAXSTATES; _container[i++]=0); + return *this; +} + +TStateset & TStateset::enclose(int el) +{ if (el< MAXSTATES && el>=0) + _container[el]=1; + return *this; +} + +TStateset & TStateset::singleton(int el) +{ empty(); + _container[el]=1; + return *this; +} + +TStateset & TStateset::cap(TStateset & s) +{ + for (int i= 0; i< MAXSTATES; i++) + _container[i]|=s._container[i]; + return *this; +} + +bool TStateset::is_empty() const +{ + for (int i= 0; i< MAXSTATES; i++) { + if (_container[i]) return FALSE; + } + return TRUE; +} + +bool TStateset::is_member(int e) const +{ + return ((e< MAXSTATES && e>=0)? _container[e] : FALSE ); +} + +int TStateset::get_first() +{ + _current=-1; + return(get_next()); +} + +int TStateset::get_next() +{ + while (_current+1 < MAXSTATES) { + if (_container[++_current]) + return _current; + } + return (-1); +} + +// ******************************* +// ******************************* +// automa per il riconoscimento di metacaratteri +#define EPSILON 0 +#define FIRST_STATE 1 +#define FIRST_NEMPTY_SYMBOL 1 + +// labels and states +bool TR_automa::is_state(int statenum) +{ + return(statenum<=_maxstate && statenum>0); +} + +// restituisce il numero dello stato con quella etichetta +int TR_automa::label2state(const char *label) +{ + for (int s=0; s<_maxstate;s++) { + if (*(st[s]._label)==label) + return(s+1); + } + return(0); +} + + +// resetta uno stato dell'automa (senza eliminarlo) +TR_automa & TR_automa::reset_state(int statenum) +{ + int _from,_to; + if (statenum>0 && statenum<=_maxstate) { + _from=statenum; + _to=statenum; + } else { + _maxstate=0; + _isdeterministic=TRUE; + _from=1; + _to=MAXSTATES; + } + { + for (int i=_from; i<=_to;i++) { + set_label(i,""); + set_final(i,FALSE); + for (int j=0; j0); + + return retv; +} + +TR_automa & TR_automa::set_final(int statenum,bool v) +{ + st[statenum-1]._final=v; + return *this; +} + +//******************* +// bows +void TR_automa::add_tran(int statenum, unsigned char symbol,int next) +{ + st[statenum-1]._transaction[symbol]=next; + if (symbol==EPSILON) + _isdeterministic=FALSE; +} + +void TR_automa::del_trans(int statenum, unsigned char symbol) +{ + st[statenum-1]._transaction[symbol]=0; +} + +int TR_automa::trans_to(int statenum, unsigned char symbol) +{ + return (st[statenum-1]._transaction[symbol]); +} + +// costruttore che crea un automa non deterministico +// (transazioni Epsilon ma nessuna transazione multipla) +// eventualmente duplica un automa (e lo rende deterministico) +TR_automa::TR_automa(TR_automa * aa,bool makedet) +{ + TStateset arrival; + TStateset newstateset; + TString16 tmplabel; + int curr_new_state; + + for (int i=0; iunion_of_closures(newstateset.singleton(FIRST_STATE)),tmplabel); + add_state(tmplabel); + curr_new_state=FIRST_STATE; + while (is_state(curr_new_state)) { + // determina l'insieme degli stati dell'automa non deterministico + // che corrispondono a questo stato dell'automa deterministico + label2set(label(curr_new_state),newstateset); + // lo stato è finale se include stati finali dell'automa non det. + set_final(curr_new_state,aa->is_final(newstateset)); + // determina tutte le transazioni + for (short symbol=FIRST_NEMPTY_SYMBOL; symboltrans_to(old_state,symbol)) + arrival.enclose(old_next); + } while ((old_state=newstateset.get_next())>0); + if (!arrival.is_empty()) { + // crea il nuovo arco nell'automa deterministico + set2label(aa->union_of_closures(arrival),tmplabel); + if (!(new_next=label2state(tmplabel))) { + new_next=add_state(tmplabel); + } + add_tran(curr_new_state,symbol,new_next); + } + } + curr_new_state++; + } + _isdeterministic=TRUE; + } // fine conversione + else + { + *this=*aa; + for (int i=0; ist[i]._label; + } + } +} + + +TR_automa::~TR_automa() +{ + for (int i=0; i0); + } while (toadd) ; + u_of_clo.cap(clo); + } while ((_state=start_set.get_next())>0); + return u_of_clo; +} + +// tenta di riconoscere la stringa passata +bool TR_automa::recognized(const char * t_str) +{ + if (_isdeterministic) { + // ricoNosce la stringa di token + int curr_state=FIRST_STATE; + for (int i=0; t_str[i]; i++) { + if (!(curr_state=trans_to(curr_state,t_str[i]))) + // fine per mancanza di trasizioni + return FALSE; + } + // fine per mancanza di caratteri di input della stringa + return (is_final(curr_state)); + } else { + // + return FALSE; + } +} + + +// ******************************* +// gestione di stringhe di metacaratteri +// ******************************* +#define C_ESCAPEMETA '\\' +#define S_BLANK 1 +#define S_DIGIT 2 +#define S_LETTER 3 +#define S_ANY 4 + +bool TMetachar::recognized(const char * s) +{ + return(_au->recognized(s)); +} + +void TMetachar::add_tran(int s,unsigned char metasymbol, int nextstate) +{ + unsigned char c; + switch (metasymbol) { + case EPSILON:// blank + _au->add_tran(s,EPSILON,nextstate); + break; + case S_BLANK:// blank + _au->add_tran(s,' ',nextstate); + break; + case S_DIGIT:// cifra + for (c='0';c<='9';c++) + _au->add_tran(s,c,nextstate); + break; + case S_LETTER: // lettera + for (c='a';c<='z';c++) + _au->add_tran(s,c,nextstate); + for (c='A';c<='Z';c++) + _au->add_tran(s,c,nextstate); + break; + case S_ANY: // qualsiasi carattere + for (c=MAXSIMBOLS-1;c>=FIRST_NEMPTY_SYMBOL;c--) + _au->add_tran(s,c,nextstate); + break; + } +} + +// restituisce la stringa di metacaratteri del linguaggio riconosciuto +const char * TMetachar::language() const +{ + return(_language); +} + +void TMetachar::set_language(const char * language) +{ + int s; + bool escaped_char=FALSE; + TString16 label("-"),nextlabel("-"); + + // crea gli insiemi di metacaratteri standard + strcpy(_metach_mand,"0LA&"); + strcpy(_metach_opz,"#9?ac"); + + + _language=language; + // crea l'automa + _au->reset_state(); + for (int i=0; language[i]; i++) { + label[0]='a'+i; + nextlabel[0]='a'+i+1; + if (language[i]!=C_ESCAPEMETA) { + if (!escaped_char) + { + // meta-caratteri e literal fuori set + switch (language[i]) { + case '0':// cifra obbligatoria + s=_au->add_state(label); + add_tran(s,S_DIGIT,s+1); + break; + case '9':// cifra opzionale + s=_au->add_state(label); + add_tran(s,EPSILON,s+1); + add_tran(s,S_DIGIT,s+1); + break; + case '#':// cifra o blank opzionale + s=_au->add_state(label); + add_tran(s,EPSILON,s+1); + add_tran(s,S_BLANK,s+1); + add_tran(s,S_DIGIT,s+1); + break; + case 'L': // lettera obbligatoria + s=_au->add_state(label); + add_tran(s,S_LETTER,s+1); + break; + case '?': // lettera opzionale + s=_au->add_state(label); + add_tran(s,EPSILON,s+1); + add_tran(s,S_LETTER,s+1); + break; + case 'A': // lettera o numero obbligatorio + s=_au->add_state(label); + add_tran(s,S_LETTER,s+1); + add_tran(s,S_DIGIT,s+1); + break; + case 'a': // lettera o numero opzionale + s=_au->add_state(label); + add_tran(s,EPSILON,s+1); + add_tran(s,S_LETTER,s+1); + add_tran(s,S_DIGIT,s+1); + break; + case '&': // qualsiasi carattere obbligatorio + s=_au->add_state(label); + add_tran(s,S_ANY,s+1); + break; + case 'c': // qualsiasi carattere opzionale + s=_au->add_state(label); + add_tran(s,EPSILON,s+1); + add_tran(s,S_ANY,s+1); + break; + default: + s=_au->add_state(label); + _au->add_tran(s,language[i],s+1); + break; + } + } else { + // escaped char + s=_au->add_state(label); + _au->add_tran(s,language[i],s+1); + } + } + escaped_char=(language[i]==C_ESCAPEMETA); + } // end of loop + // aggiunge lo stato finale + s=_au->add_state(nextlabel); + _au->set_final(s); + +} + +// ricerca caratteri del set opzionale +bool TMetachar::has_opzchars(const char * pattern) +{ + int i=0; + bool next_literal=FALSE; + + while (pattern[i]) { + if (!next_literal && strchr(_metach_opz,pattern[i])) + return(TRUE); + next_literal=(!next_literal && pattern[i]==C_ESCAPEMETA); + i++; + } + return(FALSE); +} + +// ricerca caratteri del set opzionale +bool TMetachar::has_mandchars(const char * pattern) +{ + int i=0; + bool next_literal=FALSE; + + while (pattern[i]) { + if (next_literal || strchr(_metach_mand,pattern[i])) + return(TRUE); + next_literal=(!next_literal && pattern[i]==C_ESCAPEMETA); + i++; + } + return(FALSE); +} + +// stabilisce la lunghezza della stringa di metacaratteri +int TMetachar::maxstrlen(const char * pattern) const +{ + int i=0,l=0; + bool next_literal=FALSE; + + while (pattern[i]) { + if (!next_literal) + l++; + next_literal=(!next_literal && pattern[i]==C_ESCAPEMETA); + i++; + } + return(l); +} + +// costruttore e distruttore +TMetachar::TMetachar () +{ + _au = new TR_automa; + set_language(""); +} + +TMetachar::TMetachar (const char * metastr) +{ + // crea l'automa e lo trasforma in deterministico +// TR_automa auxau; +// set_language(&auxau,metastr); + _au=new TR_automa; + set_language(metastr); + if (!_au->is_deterministic()) { + TR_automa * auxau = new TR_automa(_au,TRUE); + delete _au; + _au=auxau; + } +} + +TMetachar::~TMetachar () +{ + delete _au; +} + diff --git a/mg/mglib01.h b/mg/mglib01.h new file mode 100755 index 000000000..071f90733 --- /dev/null +++ b/mg/mglib01.h @@ -0,0 +1,116 @@ +// ******************************* +// ******************************* +#define MANY_MAG_LEV 10 +class TMag_livelli { + bool _enabled[MANY_MAG_LEV]; + int _code_lenght[MANY_MAG_LEV]; + TString _name[MANY_MAG_LEV]; + TString _picture[MANY_MAG_LEV]; + int _last_level; + +public: + int last_level() const {return _last_level;}; // Ritorna il numero di livelli abilitati + const bool enabled(int levnum=1); // Ritorna se il livello è abilitato + const TString & name(int levnum); // Ritorna il nome (descrizione) di quel livello + const TString & picture(int levnum);// Ritorna la stringa di picture per i codici gruppo di quel livello + const int code_lenght(int levnum); // Ritorna la lunghezza dei codici gruppo di quel livello + + void pack_grpcode(TString & pc, const TString &codlev, const int levnum); // Inserisce il codice del gruppo del livello levnum in pc + TString unpack_grpcode(const TString & pc, const int levnum); // Estrae il codice del gruppo del livello levnum da pc + + TMag_livelli(const char *tabname); // costruttore + ~TMag_livelli() {}; // distruttore +}; + + +// ******************************* +// ******************************* +#define MAXSIMBOLS 256 +#define MAXSTATES 25 +class TStateset { + unsigned char _container[MAXSTATES]; + int _current; +public: + TStateset & empty(); + TStateset & enclose(int e); + TStateset & singleton(int e); + TStateset & cap(TStateset & s); + int get_first() ; + int get_next() ; + bool is_empty() const; + bool is_member(int e) const; + TStateset(); + ~TStateset() {}; +}; + +struct TAutoma_state { + short _transaction[MAXSIMBOLS]; + TString16 * _label; + bool _final; +}; + +// ******************************* +// ******************************* +// automa per il riconoscimento di metacaratteri +class TR_automa { + TAutoma_state st[MAXSTATES]; + short _maxstate; +protected: + TStateset union_of_closures(TStateset &s); + + bool is_final(int statenum) const; + bool is_final(TStateset states) const; + + TR_automa & set_label(int statenum, const char *label); + bool is_state(int statenum); + const char *label(int statenum); + int label2state(const char * label); + + void del_trans(int statenum,unsigned char symbol); + int trans_to(int statenum,unsigned char symbol); + bool _isdeterministic; + +public: + TR_automa & reset_state(int statenum=-1); + + void add_tran(int statenum,unsigned char symbol,int next);// aggiunge una transizione + int add_state(const char * label);// aggiunge uno stato + TR_automa & set_final(int statenum,bool v=TRUE); // pone lo stato come finale + + bool is_deterministic() {return _isdeterministic;}; // + bool recognized(const char * s); // tenta di riconoscere la stringa passata + + TR_automa(TR_automa *a=NULL,bool makedet=FALSE); // duplica un automa (e lo rende deterministico) + ~TR_automa(); + static void set2label(const TStateset ss,TString16 & label); + static void label2set(const TString16 & label,TStateset & ss); + +}; + + +// ******************************* +// ******************************* +// riconoscimento di metacaratteri +class TMetachar { + TR_automa * _au; + TString _language; + char _metach_mand[10]; + char _metach_opz[10]; + + void set_language(const char * language); // setta l'automa che ricosce il linguaggio passato + void add_tran(int statenum,unsigned char symbol,int next);// aggiunge le transizioni all'automa +public: + const char * language() const; // restituisce la stringa di metacaratteri del linguaggio riconosciuto + bool recognized(const char * pattern); + + bool has_opzchars(const char * pattern); + bool has_mandchars(const char * pattern); + + int maxstrlen(const char * pattern) const; + const char *mand_chars() {return _metach_mand;}; + const char *opz_chars() {return _metach_opz;}; + TMetachar(const char * str); + TMetachar(); + ~TMetachar(); +}; +