Pagina 2 di 3 primaprima 1 2 3 ultimoultimo
Visualizzazione dei risultati da 11 a 20 su 22
  1. #11
    Ciao Giuseppe. Si, è possibile. Flex, in particolare, è il programma che fa al caso tuo. Scaricalo da qui:

    http://gnuwin32.sourceforge.net/packages.html

    Leggi la documentazione e gli esempi allegati e, in caso di difficoltà, chiedi pure.

    Stefano ciao, si ho letto il pvt. Purtroppo(o per fortuna, dal punto di vista economico ) sono pieno di impegni di lavoro e non ho, dunque, molto tempo. Tra l'altro, non mi intendo molto di html. Prova comunque a postare il codice che hai scritto e vediamo se riesco ugualmente a darti una mano.


  2. #12
    Utente di HTML.it
    Registrato dal
    Jun 2003
    Messaggi
    4,826
    Grazie Vincenzo.
    Il mio prolema è che dovrei fare una prima passata dei sorgenti del mio applicativo in c++ ed inserire i dati (le stringhe da tradurre)in un database.
    Poi dovrei sostituire le vecchie stringhe che ho sui sorgenti dell applicativo con un loadstring dallo string table(vc++)con l'ID corrispondente ed inserire nello string table un ID progressivo con relativo testo(quello che ho sul db).
    Utilizzo lo stringtable in quanto cosi' si puo' generare una dll con le stringhe tradotte(gli id saranno gli stessi ma cambieranno le stringhe relative).
    Infine basterà cambiare lo stringtable con un loadafxresource(dllLingua.dll)per cambiare anche runtime la lingua dell' applicativo.

    Il mio problema è gestire le varie casistiche delle stringhe e soprattuto della posizione , esistono funzioni persapere la posizione in flex?

    Poi ad es ho visto il codice di esempio che elimina i commenti , ma devo eseguire piu' di un azione , ad es eliminare i commenti e poi trovare nella parte non eliminata (il codice non commentato ) una stringa ,non raccogliendo in questo caso le stringhe nei commenti , ma se associo un azione che elimina i commenti come faccio a fare un altra azione che ricerchi le stringhe nel rimanente codice.
    Isomma sono un po confuso.

    grazie.

  3. #13
    Ciao Giuseppe,

    Flex e Bison sono due strumenti molto potenti(si, in Flex puoi gestire tutte le casistiche che vuoi) ma, per poterli sfruttare al massimo è necessario studiare la teoria degli automi.

    Un buon testo è il seguente:

    John E. Hopcroft, Rajeev Motwani, Jeffrey D. Ullman - Automi, linguaggi e calcolabilità - ADDISON-WESLEY.

    Nel tuo caso è più semplice implementare a mano un automa per il riconoscimento dei letterali stringa. Questo dovrebbe esserti di aiuto:

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <malloc.h>
    #include <tchar.h>
    
    #define MAX_STRING 2048
    
    typedef enum tagStati
    {
    	S_ERROR = -1, S0 = 0, S1, S2, S3, S4, S5, S6, S7, S8
    } Stati;
    
    typedef struct tagLista
    {
    	int		NumRigaIniziale;
    	int		NumRigaFinale;
    	char	*Stringa;
    	struct	tagLista* next;
    } Lista;
    
    Lista* NewNode(int NumRigaIniziale, int NumRigaFinale, const char *Stringa)
    {
    	int len;
    	Lista *n;
    
    	n = (Lista *)malloc(sizeof(Lista));
    
    	if( n == NULL )
    		return NULL;
    
    	len = strlen(Stringa);
    	n->Stringa = (char*)malloc(len*sizeof(char) + 1);
    
    	if ( n->Stringa == NULL )
    	{
    		free(n);
    		return NULL;
    	}
    
    	n->NumRigaIniziale = NumRigaIniziale;
    	n->NumRigaFinale = NumRigaFinale;
    	strcpy(n->Stringa, Stringa);
    	n->next = NULL;
    
    	return n;
    }
    
    Lista* Append(Lista* first, int NumRigaIniziale, int NumRigaFinale, const char *Stringa)
    {
    	Lista *n = first, *nuovo;
    
    	// catena vuota
    	if ( first == NULL )
    		return NewNode(NumRigaIniziale, NumRigaFinale, Stringa);
    
    	n = first;
    	while( n->next != NULL )
    	{
    		n = n->next;
    	}
    
    	nuovo = NewNode(NumRigaIniziale, NumRigaFinale, Stringa);
    	n->next = nuovo;
    
    	return first;
    }
    
    void Free(Lista* first)
    {
    	Lista *n1 = first, *n2;
    	while ( n1 != NULL )
    	{
    		n2 = n1->next;
    		free(n1->Stringa);
    		free(n1);
    		n1 = n2;
    	}
    }
    
    void Print(Lista *first)
    {
    	Lista *n = first;
    
    	while( n != NULL )
    	{
    		printf("Riga: %d - Stringa: \"%s\"\n", n->NumRigaIniziale, n->Stringa);
    		n = n->next;
    	}
    }
    
    Stati Automa(const char* szNomeFile, Lista** pLista)
    {
    	int NumLinea = 1;
    	int NumPrimaLinea = 1;
    
    	Stati stato = S0;
    	int z = 0;
    
    	FILE *fp; 
    
    	char str[MAX_STRING];
    	char c;
    
    	/* Apriamo il file per la lettura */
    	fp = fopen(szNomeFile, "r");
    	if ( !fp )
    	{
    		printf("Errore nell'apertura del file\n");
    		return 0;
    	}
    
    	while ( fread((void*)&c,  1, 1, fp) == 1 )
    	{
    		if ( c == '\n' )
    			NumLinea++;
    
    		switch ( stato )
    		{
    		case S0:
    			if ( c == '"' )
    			{
    				stato = S1;
    				NumPrimaLinea = NumLinea;
    			}
    			else if ( c == '/' )
    			{
    				stato = S4;
    			}
    			break;
    		case S1:
    			if ( c == '"' )
    			{
    				stato = S2;
    			}
    			else if ( c == '\\' )
    			{
    				stato = S3;
    			}
    			else
    			{
    				str[z++] = c;
    			}
    			break;
    		case S2:
    			if ( c == ' ' || c == '\t' || c == '\n' ||
                                               c == '_' || c == 'T' || c == '(' || c == ')'  )
    				;
    			else if ( c == '"' )
    			{
    				stato = S1;
    			}
    			else
    			{
    				str[z] = '\0';
    				z = 0;
    				*pLista = Append(*pLista, NumPrimaLinea, NumLinea, str);
    				if ( pLista == NULL )
    				{
    					printf("Errore nell'allocazione di memoria!\n");
    					return S_ERROR;
    				}
    				str[z] = '\0';
    				stato = S0;
    			}
    			break;
    		case S3:
    			if ( c != '\\' && c != '\n' && c != '"' )
    			{
    				str[z++] = c;
    			}
    			else if ( c == '"' )
    			{
    				str[z] = '\0';
    				z = 0;
    				*pLista = Append(*pLista, NumPrimaLinea, NumLinea, str);
    				if ( pLista == NULL )
    				{
    					printf("Errore nell'allocazione di memoria!\n");
    					return S_ERROR;
    				}
    				str[z] = '\0';
    				stato = S0;
    			}
    			break;
    		case S4:
    			if ( c == '*' )
    			{
    				stato = S5;
    			}
    			else if ( c == '/' )
    			{
    				stato = S7;
    			}
    			else
    			{
    				stato = S0;
    			}
    			break;
    		case S5:
    			if ( c == '*' )
    			{
    				stato = S6;
    			}
    			break;
    		case S6:
    			if ( c == '/' )
    			{
    				stato = S0;
    			}
    			break;
    		case S7:
    			if ( c == '\n' )
    			{
    				stato = S0;
    			}
    			break;
    		default:
    			stato = S_ERROR;
    			break;
    		}	
    	}
    
    	fclose(fp);
    	fp = NULL;
    
    	return stato;
    }
    
    int main()
    {
    	Stati stato;
    	Lista * pLista = NULL;
    
    	stato = Automa("Prova.cpp", &pLista);
    
    	printf("\n");
    
    	if ( stato == S0 )
    		Print(pLista);
    	else
    		printf("Errore!");
    
    	Free(pLista);
    
    	return 0;
    }
    La funzione Automa accetta come parametri il nome di un file sorgente e un puntatore a una lista concatenata che serve a memorizzare le stringhe. La lista memorizza anche il numero di linea.
    Per esempio, se il file "prova.cpp" contiene il seguente codice:

    codice:
    #include <iostream> 
    using namespace std; 
    
    /*
    
    Questo è un "commento"
    su più righe
    
    */
    
    // Questo è un "commento", su riga singola.
    
    int main(int argc, char *argv[]) 
    { 
    	char *pProva1 = "Questa e' una\
     stringa su due linee";
    
    	char *pProva2 = "Questa e' un'altra "
    		"stringa su due linee";
    
    	char *pProva3 = _T( "Questa e' la terza\
     stringa su due linee" );
    
    	char *pProva4 = _T( "Questa e' la quarta "
    		"stringa su due linee" );
    
    	char *pProva5 = _T( "Questa e' la quinta " )
    		_T( "stringa su due linee" );
    
    	cout << "Prova 1: " << pProva1 << endl;
    
    	cout << "Prova 2: " << pProva1 << endl;
    
    	cout << "Prova 3: " << pProva1 << endl;
    
    	cout << "Prova 4: " << pProva1 << endl;
    
    	cout << "Prova 5: " << pProva1 << endl;
          
       return 0; 
    }
    L'output del programma è il seguente:


  4. #14
    Ho modificato l'automa in modo da fargli ignorare le stringhe nei comandi del preprocessore come in:

    #include "miofile.h"

    e per fargli riconoscere correttamente le costanti speciali come \" all'interno di una stringa.

    codice:
     
    Stati Automa(const char* szNomeFile, Lista** pLista)
    {
    	int NumLinea = 1;
    	int NumPrimaLinea = 1;
    
    	Stati stato = S0;
    	int z = 0;
    
    	FILE *fp; 
    
    	char str[MAX_STRING];
    	char c;
    	char prec;
    
    	/* Apriamo il file per la lettura */
    	fp = fopen(szNomeFile, "r");
    	if ( !fp )
    	{
    		printf("Errore nell'apertura del file\n");
    		return 0;
    	}
    
    	while ( fread((void*)&c,  1, 1, fp) == 1 )
    	{
    		if ( c == '\n' )
    			++NumLinea;
    
    		switch ( stato )
    		{
    		case S0:
    			if ( c == '"' )
    			{
    				stato = S1;
    				NumPrimaLinea = NumLinea;
    			}
    			else if ( c == '/' )
    			{
    				stato = S4;
    			}
    			else if ( c == '#' )
    			{
    				while ( fread((void*)&c,  1, 1, fp) == 1 )
    				{
    					if ( c == '\n' )
    					{
    						++NumLinea;
    						break;
    					}
    				}
    			}
    			break;
    		case S1:
    			if ( c == '"' )
    			{
    				stato = S2;
    			}
    			else if ( c == '\\\' )
    			{
    				prec = c;
    				if ( fread((void*)&c,  1, 1, fp) == 1 )
    				{
    					if ( c == '\n' || c == '\r' || c == ' ' )
    					{
    						if ( c == '\n' )
    							++NumLinea;
    						stato = S3;
    					}
    					else
    					{
    						//str[z++] = prec;
    						str[z++] = c;
    					}
    				}
    				else
    				{
    					return S_ERROR;
    				}
    			}
    			else
    			{
    				str[z++] = c;
    			}
    			break;
    		case S2:
    			if ( c == ' ' || c == '\t' || c == '\n' ||
                                               c == '_' || c == 'T' || c == '(' || c == ')'  )
    				;
    			else if ( c == '"' )
    			{
    				stato = S1;
    			}
    			else
    			{
    				str[z] = '\0';
    				z = 0;
    				*pLista = Append(*pLista, NumPrimaLinea, NumLinea, str);
    				if ( pLista == NULL )
    				{
    					printf("Errore nell'allocazione di memoria!\n");
    					return S_ERROR;
    				}
    				str[z] = '\0';
    				stato = S0;
    			}
    			break;
    		case S3:
    			if ( c != '\\\' && c != '\n' && c != '"' )
    			{
    				str[z++] = c;
    			}
    			else if ( c == '"' )
    			{
    				str[z] = '\0';
    				z = 0;
    				*pLista = Append(*pLista, NumPrimaLinea, NumLinea, str);
    				if ( pLista == NULL )
    				{
    					printf("Errore nell'allocazione di memoria!\n");
    					return S_ERROR;
    				}
    				str[z] = '\0';
    				stato = S0;
    			}
    			break;
    		case S4:
    			if ( c == '*' )
    			{
    				stato = S5;
    			}
    			else if ( c == '/' )
    			{
    				stato = S7;
    			}
    			else
    			{
    				stato = S0;
    			}
    			break;
    		case S5:
    			if ( c == '*' )
    			{
    				stato = S6;
    			}
    			break;
    		case S6:
    			if ( c == '/' )
    			{
    				stato = S0;
    			}
    			break;
    		case S7:
    			if ( c == '\n' )
    			{
    				stato = S0;
    			}
    			break;
    		default:
    			stato = S_ERROR;
    			break;
    		}	
    	}
    
    	fclose(fp);
    	fp = NULL;
    
    	return stato;
    }

  5. #15
    Ciao Vincenzo,
    tu sopra dici che per richiamare un altro file dovrebbe essere sufficiente richiamare la funzione yyparse(generata da Yacc/Bison) una volta per ogni file da analizzare. Io l'ho fatto e funziona....ma se oltre a richiamare yyparse per il nuovo file da analizzare dovessi portare insieme a me un int derivante dall'analisi del file precedente? in sostanza questo int lo devo assegnare ad un parametro del mio file in flex..... che devo fare? si deve ridefinire yyparse?se si come?....mmm...forse sto facendo troppe domande

  6. #16
    Ciao Streuso,

    Ti basta dichiarare la variabile nella sezione delle definizioni del sorgente di Flex:

    codice:
    %{
    /*Sezione delle definizioni*/
    int MyVar = 0;
    %}
    
    %%
    
    /*Sezione delle regole*/
    
    %%
    
    /*Sezione subroutines utente*/
    In alternativa puoi modificare a mano, nei sorgenti .c generati da Flex e Bison, le funzioni yylex e yyparse in modo che accettino un argomento di tipo puntatore a int. All'interno della funzione yyparse devi inoltre modificare le chiamate a yylex(devi passare anche il puntatore a int).

  7. #17
    ciao vincenzo
    intanto vorrei ringraziarti perchè i tuoi consigli sono sempre esatti e precisi.
    Io faccio partire i miei programmi digitando sul prompt il nome del programma seguito da "<" e il nome del file che gli voglio passare....es "nome_programma<file.txt". adesso vorrei farlo partire digitando semplicemente "nome_programma file.txt 2", come se file.txt e il valore 2 venissero passati come variabili da assegnare al programma.Spero di essere stato chiaro.
    saluti

  8. #18
    Il codice seguente accetta, da riga di comando, il nome di un file seguito da un numero intero positivo. Se il nome del file contiene spazi, bisogna racchiuderlo tra virgolette doppie(").
    Praticamente, nella funzione main controlliamo che il numero di argomenti passati sia uguale a 3(perchè i parametri da riga di comando comprendono il nome del file eseguibile).
    Se il test va a buon fine, controlliamo, tramite la funzione VerificaIntero, che il numero passato sia in un formato valido. Se è tutto a posto, richiamiamo la funzione parse passandogli il nome del file argv[1] e il numero atoi(argv[2]).

    codice:
    /* Controlliamo che la stringa szNum rappresenti un numero intero positivo valido */
    int VerificaIntero(char *szNum)
    {
    	int Ret = 0;
    
    	if ( *szNum == '\0' )
    		return 0;
    
    	while ( *szNum++ )
    		if ( ((*szNum) < '0' || (*szNum) > '9') && *szNum != '\0' )
    			return 0;
    
    	return 1;
    }
    
    int main(int argc, char **argv)
    {
    	if ( argc != 3 )
    	{
    		fprintf(stderr, "uso: %s filename numero\nSe filename contiene spazi,"
    			            "includerlo entro virgolette doppie.\n", argv[0]);
    		return -1;
    	}
    
    	if ( !VerificaIntero(argv[2]) )
    	{
    		printf("Il numero specificato come secondo parametro non e' valido.\n");
    		return -1;
    	}
    	
    	parse( argv[1], atoi(argv[2]) );
    
    	return 0;
    }
    All'interno della funzione parse, bisogna controllare che il nome del file sia valido:

    codice:
    void parse(char *filename, int num)
    {
    	yyin = fopen(filename, "r");
    	if (yyin == NULL)
    	{
    		fprintf(stderr,"Impossibile aprire il file: %s\n", filename);
    	}
    	else
    	{
    		if (yyparse() == 0)
    			fprintf(stderr,"Parsing eseguito con successo!\n");
    		else
    			fprintf(stderr,"Parsing fallito.\n");
    	}
    }
    Ciao

  9. #19
    Volevo chiedere una cortesia ai moderatori: si può cambiare il titolo da

    [c]come fare per richiamare un fiel in (Yacc/Bison)

    a

    [c]come fare per richiamare un file in (Yacc/Bison)

    in modo da facilitare eventuali ricerche?

    Grazie

  10. #20
    ciao vincenzo,
    non capisco perche nel mio programma quando lo mando in esecuzione e faccio stampare un risultato, stampo pure degli apici...es ""19 ""....cosa puo essere?ho spulciato il programma in lungo e largo ma non capisco cosa possa essere?sbaglio col printf?boh???
    saluti

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2026 vBulletin Solutions, Inc. All rights reserved.