An old, but well-done example from ScriptWeb describes the process as follows:
"When you press Compile, the Script Editor (or whatever) calls OSACompile and AppleScript takes over. AS then parses the script into tokens and figures out which applications were referenced by the script. Then it cycles through all the apps and for each one it does these steps:
If the app has already been handled, it pulls the terminology out of AppleScript’s cache. This caches exists only as long as AppleScript is in memory. When you quit the Script Editor (or whatever), it shuts down AppleScript, freeing up its memory.
If the app is not running, then AppleScript first gets its scsz resource, which has a bit which means “always send me the GetAETE event”. Quark has this bit set. When this is set, AppleScript launches the app and performs the next step instead of this one. If the bit is not set, AppleScript simply plucks the aete resource out of the app and goes on to the next application.
If the app is running, it sends it a GetAETE event, which the app will either handle or, more commonly, ignore. If it is ignored, then AppleScript’s system handler gets called and it plucks the aete resource out of the currently open application file and returns it. Quark, for example, handles this event itself and scans its extensions folder for extensions with terminologies and returns them to AppleScript also.
OK, now we have all the terminologies in a big table. AppleScript then takes the script, which is in a mess of tokens which include spaces so they aren’t simply white space seperated, and crunches it down into a tokenized script resource. This is probably fairly time consuming and the most common operation when you compile over and over, although the first pass at accumulating the terminologies can take a fair percentage of the time which makes the initial compile slower.
AppleScript then decompiles the script into styled text and returns both that and the compiled script data to the Script Editor (or whatever) and the compile is done."