Expression Parser

medium · compilers, parsing, ast

Expression Parser

Parse a sequence of tokens into an AST for a tiny expression language.

You will receive a token slice (including EOF). Your job is to build an AST that respects precedence and associativity.

Function signature

func Parse(tokens []Token) (*Expr, error)

Grammar

expr       -> equality

equality   -> comparison ( ("==" | "!=") comparison )*
comparison -> term ( ("<" | "<=" | ">" | ">=") term )*
term       -> factor ( ("+" | "-") factor )*
factor     -> unary ( ("*" | "/") unary )*

unary      -> ("!" | "-") unary | primary
primary    -> NUMBER | IDENT | "(" expr ")" | call
call       -> IDENT "(" args? ")"
args       -> expr ( "," expr )*

AST shape

Use the provided Expr struct with the following conventions:

  • ExprNumber: Value holds the number lexeme
  • ExprIdent: Value holds the identifier name
  • ExprUnary: Value holds the operator, Left holds the operand
  • ExprBinary: Value holds the operator, Left and Right hold operands
  • ExprCall: Value holds the function name, Args holds arguments

Errors

Return a non-nil error if:

  • The tokens do not match the grammar
  • Parentheses are unbalanced
  • Extra tokens remain after parsing an expression

Notes

  • Calls are only allowed on identifiers (foo(1, 2)), not on arbitrary expressions.
  • Keep the parser readable. A simple recursive descent is perfect here.

Before implementation

Use the module’s worked reconstruction and independent debugging lab to predict an intermediate artifact first. Preserve one failing counterexample while implementing the stated API. The lesson’s transfer task uses a fresh case after the guided trace.

Run tests to see results
No issues detected
    Join Discord