What finite memory can't do
Try to design a DFA for aⁿbⁿ: some a's followed by the same number of b's. After reading the a's, the machine must remember how many there were — and with k states it can only tell k counts apart. Feed it k + 1 a's and two different counts land on the same state, so it must give the same answer for strings it should treat differently. No DFA can do it.
That argument, made precise, is the pumping lemma: any long enough string in a regular language has a middle piece that can be repeated (pumped) and the result stays in the language. Pump the a's in aⁿbⁿ and the counts no longer match — so aⁿbⁿ is not regular. Balanced brackets, nested HTML and arithmetic with parentheses all have the same problem.
Context-free grammars
A context-free grammar describes a language with rewrite rules. Upper-case letters are nonterminals that still need rewriting; everything else is a terminal that appears in the final string. Start from the start symbol and keep replacing a nonterminal by one of its rule bodies until only terminals remain. Each sequence of replacements is a derivation.
const grammar = {
start: "S",
rules: { S: ["aSb", ""] },
};
// S → aSb → aaSbb → aabbAlmost every programming language's syntax is described by a context-free grammar — the parser you'd build for it follows the rules directly. Chomsky defined these grammars in 1956 to study human language.