Master the fundamental concepts of lexical analysis through this focused micro-challenge.
You have read the whole brief, and the concepts above stay free on every task. Writing and running the code needs a plan.
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
Every task includes starter code, theory, and hidden tests so you can implement and verify locally in the browser.
How it worksLexical specifications are often written as regular expressions: [0-9]+ for integers, [a-zA-Z_][a-zA-Z0-9_]* for identifiers. Flex translates these to DFAs. Building a small regex matcher teaches you what Flex generates under the hood.
A minimal regex engine supports concatenation (ab), alternation (a|b), and Kleene star (a*). Compile the pattern to an NFA, subset-construct to a DFA, or interpret with a recursive matcher. Each match corresponds to a token pattern in your language.
cLoading…
[0-9] matches one decimal digit+ means one or more of the preceding element* means zero or moreProduction compilers embed this step inside a longer pipeline. GCC flows through cpp, cc1, assembly, and ld; Clang uses the driver, Sema, LLVM IR passes, and a target backend. LLVM bitcode, JVM bytecode, and WASM are other familiar IRs at the same layer. The exercise isolates one pass so you can test it alone before chaining it to the next stage.
You will implement a regex matcher subset that can describe token patterns for your lexer. This exercise asks you to parse simple regex syntax and test whether an input string matches, forming the foundation for generated or table-driven scanners.
Build a small regular-expression engine the way lexer generators do: parse the pattern, compile it to a Thompson NFA, and simulate the NFA over the input. Patterns describe whole tokens, so a match must cover the entire text (no substring search).
| Syntax | Meaning |
|---|---|
a | the literal character (any character without a special meaning below) |
. | any single character |
[a-z0-9_] | one character from the set; x-y is an inclusive range. No negation. |
\d \w \s | digit; word char [A-Za-z0-9_]; space or tab |
\ + any other char | that char literally, e.g. \. \* \( \[ \\ |
XY | concatenation |
X|Y | alternation (lowest precedence) |
X* X+ X? | zero or more, one or more, zero or one (bind tightest) |
( … ) | grouping; () matches the empty string |
A pattern is invalid if it has unbalanced parentheses, an unterminated [, an empty [], a trailing lone \, or a * + ? with nothing to apply to (at the start, or right after ( or |). An empty alternative such as a| is allowed and matches the empty string.
One test per line: the pattern, a single space, then the text (the rest of the line, which may contain spaces or be empty). The pattern itself never contains a space; use \s. A line with no space at all is a pattern with empty text.
cLoading…
then matches=M.
Input:
cLoading…
Output:
cLoading…
(a*)*b against 30 as must return instantly.Hidden tests cover string-literal and float patterns, nested groups, escapes, the empty text, pathological patterns, and invalid patterns.