2014-09-18 20 views
5

Sono nel mezzo della trasformazione di un normale tokenizzatore di riavvio completo (portato dal parser della lingua originale, la lingua è irrilevante qui) in uno incrementale più avanzato. Ciò implica quanto segue:Il modo migliore per salvare molte coppie di posizioni in Emacs Lisp

a) deve essere veloce, molto veloce;

b) su ogni aggiornamento di testo (sia esso inserimento o cancellazione) deve trovare i token danneggiati e riparare di conseguenza l'elenco dei token.

La versione originale del tokenizzatore crea semplicemente un elenco di token mentre scorre il testo del buffer utilizzando espressioni regolari; ogni token nella lista è un vettore di 4 elementi (['TOKENTYPE "token-lexeme" linum charnum]). Linum/charnum sono numeri semplici che specificano la posizione del token nel buffer nel momento in cui è stata eseguita la lexing. Torta facile

Ora, al punto. Ogni volta (beh .. non ogni volta, ma abbastanza spesso) un utente aggiunge o cancella un carattere (o una stringa) il nuovo tokenizzatore deve trovare un token costruito usando il testo in una posizione di modifica e, probabilmente, i token dipendenti per dopo delezioni/aggiornamenti.

Ci sono due problemi qui:

a) posizioni token dovrebbero essere dinamica (vale a dire, se un utente aggiunge un testo all'inizio di un buffer -> non dobbiamo disturbare i token di fissaggio alla fine del buffer);

b) un modo per raggiungere un token danneggiato (o molti token in generale).

In questo momento sto cercando di utilizzare le sovrapposizioni per l'attività poiché le sovrapposizioni hanno un'interfaccia piacevole che soddisfa le mie esigenze: le funzioni sovrapposizioni/sovrapposizioni aiutano la ricerca; e sovrapposizione inizio/fine spostamento in un modo appropriato.

Posso farlo felicemente per un file più piccolo. Ma si scopre (e devo ammettere che sono stato avvertito dai documenti) che la soluzione non è scalabile: anche un file LOC medio di 1K può avere overlay CONST * LOC, che è troppo per Emacs.

Questo è stato il mio primo tentativo e non è stato un successo. Sto considerando alternative come:

1) gestire un albero di ricerca di token scritto a mano usando numeri semplici;

2) stesso albero, ma utilizzando i marcatori;

3) un tipo di approccio misto che include sia numeri semplici che indicatori.

Qualsiasi alternativa agli approcci citati? O forse c'è un modo migliore per gestire un sacco di sovrapposizioni?

+0

Correlati: Ci sono 'Wisent' e' semantic' in emacs. Probabilmente, hai già controllato quelli. È inoltre disponibile un supporto per l'evidenziazione, ad esempio: http://www.gnu.org/software/emacs/manual/html_mono/semantic.html#Highlight-Func-Mode. – Tobias

+0

@Tobias Sì, certo, li ho controllati. Molte volte, in realtà, hanno persino firmato i documenti della FSF e inviato un micropatch o due per il codice relativo a Java. Questo particolare tokenizzatore ha lo scopo di funzionare in un modo diverso (si spera, superiore :-)) ed è più di un esperimento per sostituire la modalità di blocco dei caratteri. – Vlad

risposta

5

Come Lindydancer, ti suggerisco di utilizzare le proprietà di testo anziché le sovrapposizioni. Le sovrapposizioni si ridimensionano come O (N^2) mentre le proprietà del testo si ridimensionano come O (N log N), quindi funziona molto meglio. Non userei il font-lock per nessuno di questi, comunque.

Ovviamente, una soluzione alternativa è quella di correggere gli overlay: il codice C può essere modificato per renderlo O (N log N). Ho saputo come farlo per un po 'ora, ma non ho trovato il tempo (e sono improbabile che trovi il tempo in un futuro prevedibile), quindi se qualcuno fosse interessato sarei molto felice di aiutarlo a farlo.

+0

Alla fine della giornata non ho bisogno del testo stesso, ho solo bisogno di posizioni e funzioni di sovrapposizione relative alla posizione. Risulta che usare le proprietà del testo qui sarebbe una complicazione inutile ... Vado con una sorta di approccio complesso con sovrapposizioni, come l'uso di un singolo overlay per un gruppo di token. Hai menzionato la perfomance della sovrapposizione migliorando ... Mi interessa fare questo e entrare nel codice di Emacs C in generale. Cioè, se nessuno ha fretta (io non sono certamente). Come possiamo collaborare a questo? – Vlad

+0

, a proposito, sai qualcosa sull'implementazione dei marcatori? Sono potenzialmente problematici come le sovrapposizioni? – Vlad

+0

Anche i marker hanno problemi di prestazioni, sì (fa parte del motivo per cui le sovrapposizioni sono lente, poiché ogni overlay utilizza internamente 2 marker). Se sei interessato all'hacking sugli overlay, passa a emacs-devel dichiarando il tuo interesse a lavorare su questo problema e lo prenderemo da lì. – Stefan

3

Un'alternativa agli overlay è proprietà di testo, sono allegate al testo in modo diverso da quelle di sovrapposizione, quindi sono molto più efficienti.

Un pacchetto che utilizza molto le proprietà del testo è font-lock. Normalmente, è usato per evidenziare i buffer, ma non c'è nulla che ti impedisca di fare il backup su di esso per i tuoi scopi. In questo modo si otterrà l'intero sistema per rilevare che l'utente ha modificato il contenuto del buffer gratuitamente.

Nel tuo caso, è possibile sostituire l'espressione regolare in una parola chiave blocco font con una funzione che verrà chiamata con un limite di ricerca.Tutto quello che devi fare è scansionare la relativa sezione breve, impostare le tue proprietà del testo e il gioco è fatto. (Inoltre, devi impostare il blocco dei caratteri su quale proprietà stai utilizzando font-lock-extra-managed-props.)

+0

Il problema qui è che voglio ** evitare la modalità font-lock ** e sostituirlo con il sistema di tokenizzazione incrementale che farebbe l'evidenziazione della sintassi in un modo più granulare (rispetto all'uso di font-lock di espressioni regolari). In realtà, ho già controllato il codice di blocco dei caratteri e comunque non è troppo intelligente. Per quanto ho capito da uno studio veloce, si salva solo il buffer a partire dal punto di cambio (evitando un paio di casi d'angolo). – Vlad

+0

Non ho pensato alle proprietà del testo in questo modo ... Ok, posso allegare un riferimento token a una parte di testo. Un altro problema sorge qui. Come trovare i token cancellati? Cioè token che non sono indicati da nessun testo? Con le sovrapposizioni è stato piuttosto facile. – Vlad

+0

Oltre alle prestazioni, la questione se utilizzare le proprietà di sovrapposizione o le proprietà di testo implica quanto segue: associare le proprietà e i relativi valori con ** caratteri ** nel buffer o nelle posizioni ** del buffer **. Se il primo, le proprietà del testo sono una scelta naturale; se quest'ultimo, le sovrapposizioni sono. (Il titolo della tua domanda suggerisce che si tratti di posizioni del buffer, ma forse è solo perché la tua prima implementazione è basata sugli overlay.) – Drew