jueves, 5 de julio de 2012

Generador de arbol gramatical "(nivel) cadena"

#include<iostream>
#include<vector>
#include<sstream>
using namespace std;

struct Estado{
    Estado(string s, string c):simbolo(s), cadena(c){}
    string simbolo;
    string cadena;
};

int buscarTerminal(string c, string S[], int n){
    while( (--n) >= 0 ){
        if( c == S[n] )
            break;
    }
    return n;
}

int buscarNoTerminal(string c, string V[], int n){
    while( (--n) >= 0 ){
        if( c == V[n] )
            break;
    }
    return n;
}

vector<string> getTokens(string cad, string V[], int v){
    int i = 0, j , tam = cad.length();
    vector<string> tokens ;
    string actual;
    bool encontrado;
    actual = cad.substr(i,1);
    while(i<tam){
        encontrado = false;
        j = 0;
        while( j < v ){
            if(actual == V[j]){
                tokens.push_back(actual);
                encontrado = true;
                break;
            }
            ++j;
        }
        if(!encontrado){
            actual.append(cad.substr(++i,1));
            continue;
        }
        ++i;
        actual = cad.substr(i,1);
    }
    return tokens;
}

vector<string> getNivel(string estado, Estado E[], int n){
    vector<string> lineas ;
    int i = 0;
    bool encontrado = false;
    while( (i < n ) & ~encontrado ){
        if( estado == E[i].simbolo ){
            lineas.push_back(E[i].cadena);
            encontrado = true;
        }
        ++i;
    }
    while( i < n ){
        if( estado != E[i].simbolo ){
            break;
        }
        lineas.push_back(E[i].cadena);
        ++i;
    }
    return lineas;
}

vector<string> mostrarNiveles(string nivel , int nivel_raiz , Estado E[], string S[] , string V[] ,
                    int e, int s, int v, ostringstream &os){

    //cout << "MOSTRAR NIVELES 1.. " << nivel_raiz << " - NIVEL : "<< nivel << endl;

    vector<string> tokens = getTokens(nivel,V,v);
    vector<string> salida ;
    string tmp ;
    int i = 0, j, k;
    int terminal;
        //cout << "tokens : " ;
    while( i < tokens.size() ){
        //cout << tokens.at(i) << " - ";
        terminal = buscarTerminal(tokens.at(i),S,s);
        if( terminal != -1 ){
            if( salida.size() == 0 )
                tmp.append(tokens.at(i));
            else{
                k = 0;
                while( k < salida.size() ){
                    salida.at(k).append(tokens.at(i));
                    ++k;
                }
            }
        }else{
            vector<string> _tokens = getNivel(tokens.at(i),E,e);
            j = 0;
            if( salida.size() == 0 ){
                while( j < _tokens.size() ){
                    salida.push_back( tmp + _tokens.at(j) );
                    ++j;
                }
                tmp = "";
            }else{
                vector<string> _tmp ;
                while( j < _tokens.size() ){
                    k = 0;
                    while( k < salida.size() ){
                        _tmp.push_back(salida.at(k) + _tokens.at(j) );
                        ++k;
                    }
                    salida.insert(salida.begin(),_tmp.begin(),_tmp.end());
                    ++j;
                }
            }
        }
        ++i;
    }
    //cout << endl;
    i = 0;
    if(salida.size() == 0)
        salida.push_back(tmp);
    while ( i < salida.size() ){
        os << ( nivel_raiz < 100 ? "0" : ( nivel_raiz < 10 ? "00" : "" ) ) << nivel_raiz << " " << salida.at(i) << endl;
        ++i;
    }
    return salida;
}

void mostrarNiveles(vector<string> nivel , int nivel_raiz , Estado E[], string S[] , string V[] ,
                    int e, int s, int v, ostringstream &os){
    if(nivel_raiz==0)
        return;
    int i = 0;
    vector< vector < string > > tmp;
    while( i < nivel.size() ){
        tmp.push_back( mostrarNiveles( nivel.at(i), nivel_raiz, E, S, V, e, s, v , os) );
        ++i;
    }
    i = 0;
    while( i < tmp.size() ){
        //cout << "Recursividad("<<nivel_raiz<<","<<i<<")." << endl;
        mostrarNiveles( tmp.at(i), nivel_raiz-1, E, S, V, e, s, v, os );
        ++i;
    }
}

int main(){
    string V[] = {"v0","v1","v2","a","b","c"};
    string S[] = {"a","b","c"};
    Estado E[] = {
        Estado("v0","aav0"),
        Estado("v0","bv1"),
        Estado("v1","cv2b"),
        Estado("v1","cb"),
        Estado("v2","bbv2"),
        Estado("v2","bb")
    };
    vector<string> ini;
    ini.push_back("v0");
    ostringstream os;
    os << "04 v0" << endl;
    mostrarNiveles(ini,8,E,S,V,6,3,6,os);
    cout << os.str();
    return 0;
}