Esiprosessori kerää jokaisen löytämänsä #define -alkuisen rivin omaan sisäiseen listaansa. Jos tulee vastaan #undef jollekin listassa mainitulle sanalle, poistetaan sana listasta. Esikääntäjä lukee varsinaisia rivejä (ei #-alkuisia) token ("sananen") kerrallaan. Tämä token on pienin esikääntäjän ymmärtämä yksikkö (joka on erotettu ympäristöstä ei- muuttujaan sallituilla kirjaimilla). Esimerkiksi rivillä
a;bd(kissa)
on 3 tokenia: a, bd ja kissa .
Kun esikääntäjä käsittelee yhtä tokenia, etsii se sitä sisäisestä listastaan. Jos token löytyy listasta, korvataan se vastaavalla merkkijoukolla ja listan ko. token merkitään käytetyksi. Mahdollinen korvaus muodostaa 0 - n uutta tokenia. Nämä kaikki käsitellään rekursiivisesti esikääntäjän listan kanssa kunnes yhtään korvausta ei voida tehdä ( token ei löydy listasta tai kaikki listan alkiot on merkitty käytetyiksi). Näin tämä yksi token on saatu muutetuksi. Tämän jälkeen listan kaikki alkiot vapautetaan ja siirrytään rivin seuraavaan mahdolliseen tokeniin.
Miksi listaan merkitään sanoja käytetyksi? Miten kävisi muuten (kävi vanhoilla C- esikääntäjillä) seuraavan ohjelmanpätkän kanssa:
#define K T T #define T K K K T
Lyhyesti: esikääntäjä ei korvaa sisäkkäisiä #definejä heti, vaan sitten kun ne esiintyvät. Näin useissa normaalitapauksissa (kuten ei edelläkään) ei ole väliä sillä, missä järjestyksessä #define- rivit kirjoitetaan.