题目重点:从单条件判断演进为 token、AST 和可测试的布尔表达式求值,避免让生成代码替你决定未公开的语法。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 题目未明确具体字段名、比较运算符、字面量语法或错误码;训练版抽象出 Predicate(field,operator,value),比较行为需按现场题目补充。
- Part 2 的‘不考虑优先级’可能表示从左到右同级结合,也可能只给一种操作符;训练版选同级左结合,并明确这不是正式原题规格。
- Part 3 允许任意层括号,括号内外仍按训练版同级左结合;若现场题目要求 AND 高于 OR,要修改 grammar。
解题路线
- 先把 lexer、parser、evaluator 分开。lexer 逐字读 token,保留位置用于错误提示;不能对字符串直接 split(' ') 后期待括号、引号和操作符全正确。
- Part 1 将原子条件解析为独立 Predicate,字段取值和类型比较在 evaluator 处理;未知字段、null、数字与字符串比较必须由规则定义。
- Part 2 用迭代循环解析 `atom (AND|OR atom)*`,若同级左结合则每读一个运算符构造 Binary(previous,op,next)。不要依赖宿主语言默认优先级。
- Part 3 递归 `expr := primary ((AND|OR) primary)*`,`primary := predicate | '(' expr ')'`;括号缺右端、连续运算符、尾随多余 token 全部报位置化错误。先形成 AST 再按业务规则求值,允许短路但要确认是否需要收集所有 deny 原因。
- AI coding 轮先把语法/测试矩阵告诉工具,再审它生成的 lexer/AST 与错误边界;对 `A OR B AND C`、`(A OR B) AND C`、深嵌套、空表达式和非法 token 做人工独立预期,不只看 AI 自写测试。
手动走一遍
训练例 A=true、B=false、C=false。同级左结合下 `A OR B AND C` 等价 `(A OR B) AND C`,为 false;若采用传统 AND 优先级则 `A OR (B AND C)` 为 true。这个最小反例能迫使面试官确认 Part 2 所谓‘不考虑优先级’的准确含义。
规模与取舍
长度 L 的规则串做 lexer/parser O(L) 时间,AST O(L) 空间,单笔交易求值最坏 O(P) 于谓词节点数;T 笔交易共 O(L+TP),若同一规则重复用应只 parse 一次。递归深度取决于括号嵌套层数。
易错点与追问
容易失分的边界
- 让 AI 自动选 AND/OR 优先级却未与题面核对。
- 单个大函数同时 tokenize、parse 和 evaluate,后续括号追问难扩。
- 只测试有效输入,不测试孤立括号、双运算符与尾随垃圾。
- 短路求值跳过需要记录的拒绝原因却仍宣称完整诊断。
- 把 AI 能运行当作自己理解了代码结构和复杂度。
继续深挖
- 需要 AND 高于 OR 时,如何用 `or_expr/and_expr/primary` 分层语法改 parser?
- 规则量多且频繁更新时,AST 缓存和版本化如何设计?
- 如何给每次 accept/deny 生成可解释、不会泄露敏感字段的证据?
