From 7d9f9be43469748148da5cdf516cd8b32238e1f5 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Thu, 23 Apr 2026 18:58:41 +0800 Subject: 重构AST抽象 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ast/parser.rs | 52 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 15 deletions(-) (limited to 'src/ast/parser.rs') diff --git a/src/ast/parser.rs b/src/ast/parser.rs index 9add926..bfcf271 100644 --- a/src/ast/parser.rs +++ b/src/ast/parser.rs @@ -1,25 +1,26 @@ use std::{any::Any, collections::HashMap, str::Chars}; -use crate::ast::{Layer, Line, MarkdownAST, Token}; +use crate::ast::{Fragment, Line, MarkdownAST, Token}; +pub mod emphasis; pub mod headings; type ProcessFn = fn(&char, &mut ParserInternalStatus) -> ParserMatchResult; fn match_fn_list() -> Vec { - // 要求以 预处理、词、行、层、后处理 的顺序编写列表 - // 因为 词处理器 将会写入 records_tokens 由 行处理器 消费 - // 接着 行处理器 将会写入 records_lines 由 层处理器 消费 - // 最后 层处理器 将所有行写入当前层中 + // 要求以 预处理、词、行、块、后处理 的顺序编写列表 + // 然后 词处理器 将会写入 records_tokens 由 行处理器 消费 + // 接着 行处理器 将会写入 records_lines 由 块处理器 消费 + // 块处理器则将自身加入块列表中 vec![ // 预处理器 // ... // 词处理器 - // ... + emphasis::proc, // 行处理器 - headings::proc, - // 层处理器 // ... + // 块处理器 + headings::proc, // 后处理器 post, ] @@ -76,6 +77,9 @@ pub(crate) struct ParserInternalStatus<'a> { /// 记录的 Token,用于暂存无归属的 Token records_tokens: Vec, + /// 记录的 Fragment,用于暂存无归属的 Fragment + records_fragment: Fragment, + /// 临时类型表 tmp: HashMap<&'a str, Box>, } @@ -120,17 +124,19 @@ pub(crate) enum ParserMatchResult { } pub fn markdown_parser( - content: &str, + content: String, cfg: MarkdownParserConfig, ) -> Result { // 创建空 AST,无任何内容 - let ast = MarkdownAST { - root: Layer { - range_row_begin: 0, - range_row_end: 0, - lines: Vec::new(), - }, + let ast = MarkdownAST { blocks: vec![] }; + + // 在末尾添加换行符,以确保末尾行一定能被执行 + let mut content = content; + let ending = match cfg.ending_rule { + LineEndingRule::CRLF => "\r\n", + LineEndingRule::LF => "\n", }; + content.push_str(ending); // 初始化内部状态 let mut inr = ParserInternalStatus { @@ -142,6 +148,7 @@ pub fn markdown_parser( col: 0, records_lines: Vec::new(), records_tokens: Vec::new(), + records_fragment: Fragment::default(), tmp: HashMap::new(), }; @@ -165,6 +172,9 @@ pub fn markdown_parser( // 当前处理函数的索引值 let mut idx: u8 = 0; + // 该字符是否已完成处理 + let mut done = false; + for v in &match_vec { // 当前处理函数在放弃列表中 if aborted.contains(&idx) { @@ -180,8 +190,13 @@ pub fn markdown_parser( // // 在 `post` 中,必须处理该字符的换行逻辑,否则会产生字符位置指针异常 if !matches!(c, '\r' | '\n') { + // 为字符标记为已完成处理 + done = true; + // 跳过当前步骤前,提前将列指针右移 inr.col += 1; + + // 所有处理器跳过当前步骤 break; } } @@ -213,9 +228,16 @@ pub fn markdown_parser( )); } } + + // 下一个处理器继续处理 idx += 1; } + if !done { + // 如果字符未完成处理,说明是普通字符,需要加入 records_fragment + inr.records_fragment.str.push(c); + } + // 将列指针右移 inr.col += 1; } -- cgit