Reported September 2026
Attentivestack

Lisp Expression Parser

Reported by candidates from Attentive's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.

Get StealthCoderRuns invisibly during the live Attentive OA. Under 2s to a working solution.
Founder's read

Attentive reportedly put this Lisp expression parser in front of candidates in September 2026. The mistake that sinks a first attempt is treating it like a string-replace job: swap spaces for commas, wrap atoms in quotes, done. It breaks on adjacent parentheses, empty lists, and commas landing in the wrong place. This is a stack or recursive descent problem in disguise. You tokenize, then build the output as you go. If you've got an OA coming, know the shape before you open the editor. StealthCoder is there as a safety net if you blank during the live assessment.

The problem

Parse expression as one Lisp-style expression and return the canonical JSON serialization of its syntax tree as a string.
An atom is a nonempty maximal sequence of ASCII letters, digits, underscore, plus, minus, asterisk or slash. Preserve its exact characters and case, including leading zeros and signs.
A list consists of an opening parenthesis, zero or more expressions, and a closing parenthesis. Lists may nest.
ASCII space, tab, line feed and carriage return separate tokens and may occur before or after the root. Parentheses are standalone tokens even when adjacent to atoms or other parentheses.
The input is valid and contains exactly one root expression. Adjacent atoms must be separated by whitespace; parentheses already provide token boundaries.
Serialize every atom as a JSON string and every list as a JSON array of its children, preserving their order and nesting. Use commas between children and no whitespace outside quoted atom strings. The allowed atom characters never contain a quote or backslash. An empty list becomes [].
Do not evaluate operators, resolve names, change numeric-looking atoms into numbers, or flatten nested lists. For example, the atom 001 remains the JSON string "001". The function returns the serialized text, not a native nested array.

Function
parseLispExpression(expression: String) → String

Examples
Example 1
expression = " (add 1 (mul 2 3)) "
return = "[\"add\",\"1\",[\"mul\",\"2\",\"3\"]]"
The outer list has three children. Its last child is another list. Operator names and numbers are all strings; no multiplication or addition is performed.
Example 2
expression = "(a (b) ())"
return = "[\"a\",[\"b\"],[]]"
The nested one-element list and the empty list remain distinct child arrays. Whitespace outside atoms is not part of the canonical output.

Constraints
1 <= expression.length <= 5000.
There are at most 2000 tokens, counting each parenthesis and each atom once.
At most 100 lists are open at the same time.
The expression follows the stated grammar and contains exactly one root.

Reported by candidates. Source: FastPrep

Pattern and pitfall

The trick is a clean two-step: tokenize, then serialize. Scan the string once. Parentheses are their own tokens. Whitespace splits atoms. Everything else accumulates into an atom. Then parse recursively: on an atom, return its quoted text. On "(", collect children until ")", join them with commas, and wrap in brackets. An empty list falls out for free as []. The classic pitfall is comma placement. Don't append a comma after every child, join instead. Another is ignoring the root's surrounding whitespace. With at most 100 open lists, recursion depth is safe, but an explicit stack works too. Don't convert numbers, don't flatten, keep 001 as "001". If the recursion or index bookkeeping slips live, StealthCoder can hand you a working version while you're mid-assessment.

Drill it cold or hedge it with StealthCoder. Either way, don't walk into the OA hoping you remember the trick.

If this hits your live OA

You can drill Lisp Expression Parser cold, or you can hedge it. StealthCoder runs invisibly during screen share and surfaces a working solution in under 2 seconds. The proctor sees the IDE. They don't see what's behind it. Made for the candidate who got the OA invite this morning and has 72 hours, not six months.

Get StealthCoder

Related leaked OAs

⏵ The honest play

You've seen the question. Make sure you actually pass Attentive's OA.

Attentive reuses patterns across OAs. Made for the candidate who got the OA invite this morning and has 72 hours, not six months. Works on HackerRank, CodeSignal, CoderPad, and Karat.

Lisp Expression Parser FAQ

What's the trick to the Lisp Expression Parser problem?+

Separate tokenizing from building. Turn the input into tokens of parens and atoms, then parse recursively. Atoms become quoted strings, lists become comma-joined children wrapped in brackets. Once tokens are clean, the serialization is about ten lines.

How hard is this really?+

Medium. There's no clever algorithm, just careful implementation. The difficulty is handling adjacent parentheses, empty lists, and comma placement without off-by-one errors. If you've written a small recursive descent parser before, it's quick.

Should I use recursion or an explicit stack?+

Either works. Nesting is capped at 100 open lists, so recursion depth is no risk. A stack of child lists is also easy: push on "(", pop and join on ")". Pick whichever you can write without bugs under pressure.

What edge cases break first attempts?+

Empty lists like (), nested single-element lists like (b), parentheses touching atoms like (a(b)), and whitespace including tabs and carriage returns around the root. Also keep atoms exactly as given, so 001 stays "001" and case is preserved.

How do I prepare for this in 48 hours?+

Write the tokenizer and recursive parser from scratch twice, then test on both examples plus (), ((())), and a lone atom. Stick to join for commas. Don't evaluate anything. That covers nearly every failure mode this problem has.

Problem reported by candidates from a real Online Assessment. Sourced from a publicly-available candidate-aggregated repository. Not affiliated with Attentive.

OA at Attentive?
Invisible during screen share
Get it