the scanner (lexer)
/ LEK-ser /
Before you can understand a sentence you must first see it as words, not a blur of letters. Reading 'thecatsat' is hard until you chunk it into 'the cat sat'. The scanner, also called the lexer, does exactly this chunking for a compiler: it reads the raw stream of characters and groups them into tokens, the meaningful words of the language, throwing away whitespace and comments along the way.
The scanner is built from regular-language machinery, which is the layer below grammars. Each kind of token, an identifier, an integer, a keyword, an operator, is described by a regular expression, and the scanner is effectively a finite automaton (DFA) that runs over the characters and reports each token it recognizes. The standard rule is maximal munch (longest match): at each point it grabs the longest run of characters that forms a valid token. So < = is two tokens but <= is one, and the scanner prefers the longer one. The scanner does not understand nesting or balance, brackets are just punctuation tokens to it, because regular languages cannot count; that is the parser's job.
Splitting scanning from parsing is a deliberate division of labour that pays off in speed and simplicity. The scanner does the high-volume, character-by-character work with a fast finite automaton, so the parser can work on a short clean token stream instead of raw text, and can use the simpler, more powerful theory of context-free grammars without drowning in spelling details. This two-layer design, regular scanner feeding a context-free parser, is the standard architecture of essentially every real compiler.
Scanning the line if (x>=10) produces the token stream [keyword:if, (, id:x, >=, num:10, )]. The scanner skips the spaces, treats >= as one operator token (longest match, not > then =), and never asks whether the parentheses balance.
The scanner is a fast finite automaton turning characters into tokens, using longest-match.
The scanner is regular, not context-free: it cannot check that brackets are balanced or that an if has a matching else. Anything requiring counting or nesting is deferred to the parser.