2010-07-20 10 views
5

Sono passati alcuni anni da quando ho dovuto analizzare qualsiasi file più difficile di CSV o XML, quindi sono fuori allenamento. Mi è stato dato il compito di analizzare un formato di file chiamato NeXus in un'applicazione Delphi.Come si analizza un formato di file complesso in Delphi? (Non CSV, XML, ecc.)

Il problema è che non so da dove iniziare, devo usare un tokenizer, regex, etc? Forse anche un tutorial potrebbe essere quello di cui ho bisogno a questo punto.

risposta

7

Dai un'occhiata allo GOLD Parser. È un sistema di meta-analisi che consente di definire una grammatica formale per un formato di lingua/file. Crea un file di regole di analisi che viene inserito in un tokenizer, insieme al file di input, e crea un albero di sintassi in memoria.

Esiste un'implementazione Delphi del tokenizer disponibile sul sito web. Rende l'analisi molto più semplice da quando lexing e tokenizing sono già presi in considerazione per te, e tutto ciò di cui ti devi preoccupare è definire i token in una grammatica formale e quindi interpretarli una volta che sono stati analizzati.

+0

Sto controllando GOLD Parser ora. – Daisetsu

+0

Solo una FYI supporta solo BNF e non EBNF, il che rende piuttosto doloroso lavorare con. – Daisetsu

+2

Sì, sono d'accordo, il supporto EBNF lo renderebbe più semplice. :( –

2

Oltre alla risposta molto bella di Mason. C'è una piccola grande classe in Delphi che è spesso sottovalutata, e una che si può imparare una tecnica veramente bella da e questa è la classe PageProducer.

Dai un'occhiata al modo in cui analizza l'HTML e affronta eventi su cose come trovare tag, attributi ecc. Non sto dicendo di usare PageProducer (perché non sarai in grado di usare Nexus) ma è molto tecnica semplice, elegante e potente.

3

check this out, è commerciale, ma sembra un giocattolo divertente:

http://dpg.zenithlab.com/

Ma, in realtà: per Nexus non hai bisogno di un parser complicata.

Un po 'di codice di controllo della posizione e alcuni conteggio delle stringhe e delle parentesi, e l'hai scritto.

vorrei analizzare utilizzando un semplice parser token-at-a-time come questo:

  1. file di caricamento in un TStringList.
  2. per ogni riga, prendi un token alla volta per determinare il tipo di linea.
    hanno un tipo enumerato per questo tipo di linea.
  3. la prima linea non vuota valida deve essere rilevata come tag #nexus valido.
  4. successivo all'area dell'intestazione (saltato per lo più sembra)
  5. begin è il primo e parola chiave sulla linea.
  6. le righe seguenti all'interno del blocco iniziale sembrano quasi un comando DOS e i relativi parametri della riga di comando e sono separate da spazi e terminano con il punto e virgola. praticamente come pascal, ma parentesi.

Per quanto sopra vorrei codice per me un piccolo set di aiutanti, e, infine, una delle cose che potrebbero aver bisogno di scrivere è un po 'funzione di splitting del token in questo modo:

funzione GetToken (var inputString: String; outputToken: String; const Separators: TStrings; Parole chiave: TStrings; ParenFlag: Boolean): Boolean;

GetToken restituisce true quando è stato in grado di trovare e restituire una stringa di token da inputString, salta gli spazi bianchi iniziali e termina quando trova un separatore. I separatori sono oggetti come spazio o virgola.
ParenFlag: True significherebbe che il token successivo che ottengo dovrebbe essere un intero elenco di articoli con parentesi. Una volta ottenuta l'intera lista parentesi (((a, b), (c, d), (e, f))), chiamerei un'altra funzione che decomprimerebbe il contenuto di quella lista in una struttura dati per le liste/array.

Non è consigliabile il motore parser grande e il comando grammaticale BNF consente di scrivere il codice se si scrive una grammatica BNF prima di scrivere il parser. Ma non c'è niente di così brutale qui da non poterlo analizzare.

Ci si aspetta che faccia query/trasformazioni su questo? Pensi di aver bisogno di convertirlo in json o xml per lavorare ulteriormente con esso?

+2

Una spiegazione soddisfacente, sarebbe comunque lontana dal caricamento con tstringlist. Mette inutilmente un limite al file (+/- metà della memoria disponibile per la tua app) –

+1

DPG sembra essere un vecchio progetto, l'ultima versione era nel 2002. Questo non sarebbe necessariamente un problema, ma nel caso particolare di Delphi, non investirei denaro (molto meno tempo) in una tecnologia che non ha funzionato con Delphi Unicode. –

+1

Se arrivasse con la fonte, potrei portarlo avanti in poche ore, ma sì, il fatto che lui elenchi solo Delphi 7 e di nuovo come compatibile ti dica, è morto. Vorrei che lo aprisse e io aggiusterò per lui –

2

Non è stato ancora trovato un formato di test in cui una macchina di stato non analizzerà. Aggiungi in ricorsione per far scorrere i nidi sugli alberi. Si tratta di un motore di analisi relativamente veloce, facilmente elaborabile, che può essere creato praticamente per qualsiasi file di testo con motivi. Spesso più semplice dell'uso di un linguaggio di scripting per l'avvio. Ho personalizzato quelli scritti per HTML, XML, HL7 e una varietà di formati EDI medici.

+1

Th è un buon modo per farlo in realtà. È possibile avere un oggetto di stato di analisi che contiene una funzione della macchina di stato e variabili di stato e metodi come "Riavvolgi" e "NextSymbol: String" e Eof: Boolean. –

Problemi correlati