2011-01-18 7 views
8

Sto scrivendo un semplice tokenizer javascript che rileva i tipi di base: Word, Number, String, RegExp, Operator, Comment e Newline. Tutto sta andando bene, ma non riesco a capire come rilevare se il carattere corrente è delimitatore RegExp o operatore di divisione. Non sto usando le espressioni regolari perché sono troppo lente. Qualcuno conosce il meccanismo per rilevarlo? Grazie.Conflitto di divisione/RegExp durante la tokenizzazione Javascript

risposta

6

È possibile sapere quale è il token precedente nello stream. Passa attraverso ogni token che il tuo lexer emette e chiedi se può essere ragionevolmente seguito da un segno di divisione o da un'espressione regolare; scoprirai che i due set di token risultanti sono disgiunti. Ad esempio, (, [, {, ; e tutti gli operatori binari possono essere seguiti solo da un'espressione regolare. Allo stesso modo, ), ], }, identificatori e stringhe/numeri letterali possono essere seguiti solo da un segno di divisione.

Vedere la sezione 7 del ECMAScript spec per ulteriori dettagli.

+2

ho scritto un tokenizzatore una volta, e questi sono i ER che rilevano un "innesco regex": '/ [{(\ [;,] /' '/ \ + \ + | - | ~ | && | \? |: | \ | \ || \\ $ | (<<|> >>? | ==? |! =? | [- <> + *% & \ | \^/]) =?/'//(? = \ s | \/| user123444555621

+4

Tecnicamente, ci sono un paio di ambiguità che sono inevitabili al livello lessicale, ad esempio '(a + b)/c' contro' if (x) /foo/.exec ('bar') '(può essere preceduto da close-paren). Inoltre,' ++/foo/.abc' e 'a ++/b' (anche plus-plus possono precedere) Insieme a' --' questi sono gli unici che conosco. – dgreensp

+0

@dgreensp Grazie osservazioni molto utili !!! – Zo72

1

è necessario controllare il contesto quando si incontra la barra. se la barra è dopo un'espressione, allora deve essere divisione, o è un inizio regexp.

per riconoscere il contesto, forse è necessario creare un parser di sintassi.

ad esempio

function f() {} 
/1/g 
//this case ,the slash is after a function definition, so it's a refexp start 


var a = {} 
/1/g; 
//this case, the slash is after an object expression,so it's a division 
Problemi correlati