ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

bx::Scanner:告别复杂解析器,简化扫描任务!

2026/8/7 17:34:15 拓冰建站 浏览量
bx::Scanner:告别复杂解析器,简化扫描任务!

主页菜单

包含 [主页]、[文章]、[文档]、[个人简介] 等链接,还有浅色、深色模式选择。

解析器不必复杂

2026 年 7 月 27 日发布,文章包含引言、设计、结论等部分。

引言

几年前为 bgfx 编写着色器前端解析器,使用 Lemon 解析器生成器,但其生成代码难读且陌生,语法变化时需重新熟悉结构,最终放弃。对于小任务编写临时解析器,虽速度快无依赖,但存在重复模式和易出错问题。临时解析代码示例展示了常见模式,作者想要介于两者之间的工具,即 bx::Scanner,它既不是解析器生成器也不是解析表达式文法库。

设计

bx::Scanner 围绕一组约束条件构建:零拷贝且不拥有数据,结果为 StringView 直接指向原始输入;单光标且不会自动移动,有相关操作方法;内置行号和列号跟踪,方便生成错误消息;使用字符类而非迷你语言,特殊情况可用谓词;接口简洁,公共接口在小的头文件中。工作流程是在 StringView 上构造 Scanner,使用 peek 和 accept 方法扫描。accept 方法消耗匹配文本并返回 StringView,peek 方法不移动光标执行测试。判断成功匹配方式为!scanner.accept('=').isEmpty(),虽繁琐但匹配文本随结果返回。

最简单的助手:LineReader

LineReader 会将输入分割成多行,处理换行符并去除多余尾随 。循环条件应使用 isDone 判断是否结束,而不是直观但错误的 while (!lr.next().isEmpty() )。

INI 解析与子扫描器

Scanner 可从 StringView 构造,一行文本可成为独立扫描器,子扫描器能避免临时解析器中常见的错误,将内部扫描器范围限制在一行内,防止超出格式错误行的范围。

URL 解析及空值的含义

匹配结果以 StringView 形式返回,“匹配为空”和“未匹配”返回相同值,空令牌是合法令牌,如 URL 可能无路径或用户信息。经验法则是返回值是令牌,peek 或 accept 用于回答结构问题,解析 URL 只需 75 行代码。

文件路径规范化

路径处理需处理驱动器号、分隔符等,分隔符用谓词匹配。扫描器任务是一次传递一个组件,.. 的处理会回退输出,扫描器避免了以前容易出错的部分。

堆栈跟踪符号化

将 atos 或 addr2line 的输出行转换为函数名、文件名和行号,可替代复杂操作。空的函数名无法区分“缺失”和“为空”,只需检查返回值。

结论

第一次需要此类工具是处理 addr2line 输出时,产生的 strConsumeTo 成为 bx::Scanner 的核心。使用 bx::Scanner 成功删除了 INI 库依赖和多次手动编写的相同循环。若编写指针追逐循环跳过空白字符并收集标识符,可考虑使用类似工具,解析器不必复杂。

还有一件事……

使用 bgfx 目标是为游戏开发者提供跨平台、与图形 API 无关的渲染库,简化移植过程,确保性能和兼容性。若喜欢文章并支持目标,可成为赞助商。