Parse Boolean Rule Expressions
Reported by candidates from Stripe's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
The edge case that kills a naive Stripe solution on this one is the integer literal. "+003" has to become 3 and "-0" has to become 0, and most people only notice after a hidden test fails. Stripe reported this OA in September 2026. It's a tokenizer plus a recursive descent parser for Boolean rules, and the output is a canonical prefix string. The grammar is small, but the details are mean: escapes in strings, reserved uppercase words, and a hard INVALID on any malformed input. If you blank on the parser structure, StealthCoder is the safety net running invisibly during the live OA.
The problem
Given one string rule, parse it as a Boolean rule expression. Return a canonical prefix serialization of its abstract syntax tree, or return INVALID when the complete input is malformed. Tokens An identifier starts with an ASCII letter or underscore and continues with ASCII letters, digits, or underscores. The uppercase words NOT, AND, and OR are reserved. An integer literal has an optional + or - followed by one or more decimal digits. A string literal is enclosed in double quotes and contains printable ASCII characters. Inside a string, \" represents a quote and \\ represents a backslash; no other escape is valid. The comparison operators are ==, !=, <, <=, >, and >=. Spaces, tabs, carriage returns, and newlines outside strings are insignificant. Keywords are case-sensitive. Grammar and precedence Every comparison has exactly the form identifier comparison-operator literal, where the literal is an integer or string. Comparisons and parenthesized expressions are operands for the Boolean operators. NOT has the highest Boolean precedence and associates to the right, so repeated NOT operators are allowed. AND has the next precedence and associates to the left. OR has the lowest precedence and associates to the left. Parentheses may override precedence and may be nested. Canonical serialization A comparison becomes (operator identifier literal). A negation becomes (NOT expression). A conjunction or disjunction becomes (AND left right) or (OR left right). Integer literals omit a leading + and leading zeros; every zero, including negative zero, becomes 0. String literals remain quoted and use only \" and \\ escapes in the result. A lexical error, an incomplete comparison, an unexpected token, an empty expression, or mismatched parentheses makes the complete result INVALID. Function parseRuleExpression(rule: String) → String Examples Example 1 rule = "age >= 18 AND country == \"US\"" return = "(AND (>= age 18) (== country \"US\"))" Each comparison is serialized first. Because AND joins the two comparison nodes, it becomes the root. Example 2 rule = "NOT (status == \"blocked\" OR retries > +003)" return = "(NOT (OR (== status \"blocked\") (> retries 3)))" The parentheses make OR the child of NOT. The signed integer +003 is canonically written as 3. Example 3 rule = "age >= AND active == 1" return = "INVALID" The first comparison has no literal after >=, so the complete expression is malformed. Constraints The input is an ASCII string and contains at most 200000 tokens. Parenthesis nesting is at most 1000. Every identifier and every decoded string literal has length at most 100. Inputs that violate the token, nesting, or token-length rules return INVALID.
Reported by candidates. Source: FastPrep
Pattern and pitfall
The trick is to split the work into two clean passes. First, tokenize: identifiers, signed integers, strings with only \" and \\ escapes, comparison operators (match two-character ones first), parentheses, and reserved NOT, AND, OR. Any lexical error returns INVALID immediately. Second, parse with precedence climbing or three functions: parseOr calls parseAnd, which calls parseNot, which calls parsePrimary. NOT recurses into itself for right associativity. AND and OR loop for left associativity. The pitfalls: forgetting to check that all tokens were consumed, accepting a comparison without a literal, treating NOT as a valid identifier, and normalizing integers wrongly. Strip the sign and leading zeros, and map negative zero to 0. With nesting up to 1000 and 200000 tokens, watch recursion depth in your language, and enforce the nesting and length limits yourself. If the parser design slips under pressure, StealthCoder is the hedge on the live OA.
If this hits your live OA and you blank, StealthCoder solves it in seconds, invisible to the proctor.
You can drill Parse Boolean Rule Expressions 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. Built by an Amazon engineer who would have shipped this the night before his JPMorgan OA if he'd had it.
Get StealthCoderRelated leaked OAs
You've seen the question.
Make sure you actually pass Stripe's OA.
Stripe reuses patterns across OAs. Built by an Amazon engineer who would have shipped this the night before his JPMorgan OA if he'd had it. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Parse Boolean Rule Expressions FAQ
How hard is the Stripe Parse Boolean Rule Expressions question really?+
Medium-hard on paper, but the logic is standard. The difficulty is volume of small rules: escapes, reserved words, integer normalization, and INVALID handling. If you've written a recursive descent parser once, it's very doable. If you haven't, the structure will feel unfamiliar.
What's the core trick for the precedence rules?+
Use one function per precedence level. parseOr loops over AND results, parseAnd loops over NOT results, and parseNot recurses on itself when it sees NOT. Loops give left associativity, self-recursion gives right associativity. Primary handles parentheses and comparisons.
Which edge cases should I test first?+
Test "+003", "-0", "-007", strings with escaped quotes and backslashes, an invalid escape like \n, a missing literal after an operator, an empty input, unbalanced parentheses, and trailing tokens after a complete expression. Also try NOT NOT x == 1 and a lowercase "and", which is an identifier, not a keyword.
Do I need to worry about recursion depth?+
Nesting is capped at 1000, so recursion is usually fine, but each level may use several stack frames across your precedence functions. Track depth and return INVALID above 1000. If you're nervous, an explicit stack parser works, though recursive descent is simpler to write.
How do I prepare for this in 48 hours?+
Write a tokenizer and a three-level recursive descent parser from scratch, twice. Then write a dozen invalid inputs and confirm each returns INVALID. Practice the integer canonicalization separately. Parsers are about structure, so rehearsing the skeleton matters more than memorizing details.