Master the fundamental concepts of syntax 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 worksWhile expressions compute values, statements perform effects: assignment, control flow, return. C's grammar separates statement parsing from expression parsing because dangling-else and declaration-vs-expression ambiguities require distinct code paths. GCC's parser and Clang's ParseStmt routines mirror this split.
Assignment: id = expr;. If-else: if (expr) stmt else stmt. While: while (expr) stmt. Return: return expr;. Block: { stmts }. Each form starts with a distinguishing token or identifier pattern.
cLoading…
;) are valid in C}Production 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 statement parsing functions that recognize assignments, conditionals, loops, returns, and blocks. This exercise asks you to extend your parser beyond expressions and produce statement AST nodes the semantic analyzer can walk.
Extend the expression parser from Recursive Descent Parser to statements, and print the statement tree.
A sequence of statements on stdin (any layout, any number of lines).
Tokens are those of the previous task plus the keywords if else while return, the assignment operator =, ;, { and }. Keywords are never identifiers.
cLoading…
equality and everything below it are exactly as in the previous task. Assignment is right-associative: a = b = 1 is (= a (= b 1)). An else belongs to the nearest unmatched if.
Each statement on its own line, children indented by two spaces; expressions print as S-expressions like the previous task, with assignment as (= NAME VALUE):
| Statement | Printed as |
|---|---|
{ ... } | BLOCK, then its statements indented |
if (c) s | IF c, then s indented |
if (c) s1 else s2 | IF c, s1 indented, ELSE at the same indent as IF, s2 indented |
while (c) s | WHILE c, then s indented |
return; / return e; | RETURN / RETURN e |
; | EMPTY |
e; | EXPR e |
After the tree print statements=N, the number of statement nodes at every depth.
Stop at the first error and print only error at LINE:COL: MESSAGE, where the position is that of the offending token (lines and columns start at 1; end of input is the position just past the last character). Messages:
unexpected character 'X'expected expressionexpected '(' / expected ')' / expected ';' / expected '}'invalid assignment target: reported at the = when its left side is not a plain identifier (e.g. 1 = x;)Input:
cLoading…
Output:
cLoading…
The else binds to the inner if.
parse_block, parse_if, parse_while, parse_return, ...) dispatched from parse_statement.Hidden tests cover nested blocks and loops, return;, empty statements, chained assignment, and an invalid assignment target.