Well, you can do the validation in "OkKeyUp" / "OnUtf8KeyUp" / "On[Text]Changed", when the new char has been added.
A more advisable form would be to schedule an "OnIdle" (or even IdleTimer, with 100 ms) in either of the above events.
I have the feeling though, that is not what you asked, rather you want to know how to go about parsing the text?
And (in the context of a programming language) this is an
advanced topic. So you will need to do some reading up yourself.
There are several existing Parsers in Lazarus/FPC. You can look at them for learning, and some can be configured and be used as a base for your work (there is a parser in the FCL / I don't recall the name / I never used it, can't tell if it will serve your purpose).
Obviously something like an "if" is easy to parse. You then need to add some sort of context keeping (you could use a "state" / their is a design pattern / google it).
E.g., the State after "if" would be
"inside bool expression".
"page" would be an unknown word, therefore treated as variable. (or you have a list keeping track of variables). .... And so forth.
You also count open/close brackets within each state block "()[]".
So when you reach "{" all "(" since the "if" must have been closed.
"{" ends the
"inside bool expression". It starts a section
"code block"Sections can be nested too. You can have an "if" inside a "code block".
(Google and learn about "stacks" (FIFO lists), linked lists. / BTW a TList works fine for FIFO)
As the text gets bigger, scanning the whole text may take more time. If it takes more than 50..100 milliseconds, the user will notice this as a lag in reaction time in your app.
So you need to find points where to save the state (context), and only scan modified parts. (You can also do work in threads, but that is on top of all else)
While the SynEdit Highlighter does not do Syntax checks, it does have the concept of saving context for each line, and therefore being able to minimize work.
It is explained in
https://wiki.lazarus.freepascal.org/SynEdit_Highlighter (see "ranges" and "context" / "ranges" is just the name used in the HL to refer to context)