C++ Markdown解析器基于状态机逐字符扫描,支持标题、加粗、斜体、段落、换行和无序列表;按行读取并行内遍历,状态包括NORMAL、EMPHASIS、HEADER、LIST_ITEM、LINE_BREAK;内联格式递归解析,输出HTML或轻量AST。

用C++实现一个简单的Markdown解析器,核心思路是**基于状态机的逐字符扫描**,不依赖外部库,适合学习文本处理与有限状态机(FSM)设计。重点不是覆盖全部规范,而是抓住常用语法(标题、加粗、斜体、段落、换行、无序列表),结构清晰、可扩展。
状态机设计:定义关键状态与转移
解析过程本质是“读入字符 → 判断当前上下文 → 更新状态 → 生成对应HTML或AST节点”。定义几个核心状态:
-
STATE_NORMAL:普通文本,遇到
*、#、-等触发状态切换 -
STATE_EMPHASIS:进入斜体(单
*或_)或加粗(双**或__)的中间状态,需回溯匹配闭合符号 -
STATE_HEADER:连续读到1–6个
#后紧跟空格,进入标题识别,后续为标题内容 -
STATE_LIST_ITEM:以
-开头的行,视为无序列表项,注意缩进和嵌套(本简化版暂不支持嵌套) -
STATE_LINE_BREAK:行末两个及以上空格,生成
逐行+逐字符解析:兼顾效率与可控性
不一次性加载全文做正则替换,而是按行读取(std::getline),每行内部再遍历字符。好处是:
- 天然支持段落切分(空行分隔)
- 方便识别行首语法(如
## 标题、- 列表项) - 状态在行内维护,跨行状态(如代码块)可后续扩展
示例片段(伪代码逻辑):
立即学习“C++免费学习笔记(深入)”;
if (line starts_with("# ")) { state = HEADER; level = 1; content = line.substr(2); }文本转义与内联解析:优先级与回溯
内联格式(如**bold**)需在段落文本中二次扫描。关键点:
- 从左到右扫描,遇到
*时,检查后续是否构成**或*text* - 使用简单回溯:记录起始位置,找到匹配闭合符后,将中间内容递归解析(支持嵌套如
**加粗里有*斜体*) - 转义字符
\*需跳过,避免误匹配 - 建议封装一个
parseInline(const string& s) -> vector,返回文本/强调/链接等节点
输出结构:轻量AST或直接生成HTML
初学者可先直出HTML字符串(易调试);进阶可构建简单AST:
- 节点基类
Node含type(PARAGRAPH、STRONG、EM、TEXT等)和children - 叶子节点存原始文本(已转义),容器节点存子节点列表
- 最后统一
render()成HTML,便于后期支持PDF、ANSI颜色等多目标输出
比如输入"# Hello\n\n- **yes**\n- _no_",应输出类似:
Hello
- yes
- no
基本上就这些。不复杂但容易忽略状态重置、边界条件(如行尾符号、空行处理)、以及转义逻辑——写完后用几组典型测试用例(GFM片段)跑一遍,就能快速定位问题。











