UNPKG

recogn-parse

Version:

recogn-parse 提供了 识别--解析 的机制,使用者只需要添加识别器 和 解析器,然后就可以对事件进行识别和解析,适合用所有具备 识别--解析 流程的场景中,如:加载并显示各种模型、预览文件等

107 lines (78 loc) 7.25 kB
[识别解析_时序图]: ./assets/识别解析_时序图.png [识别解析_活动图]: ./assets/识别解析_活动图.png [对鉴定者列表执行识别]: ./assets/对鉴定者列表执行识别.png [执行鉴定者]: ./assets/执行鉴定者.png [识别]: ./assets/识别.png [执行鉴定者]: ./assets/执行鉴定者.png [解决]: ./assets/解决.png **目录:** <!-- @import "[TOC]" {cmd="toc" depthFrom=1 depthTo=6 orderedList=true} --> <!-- code_chunk_output --> 1. [类的关系](#-类的关系) 2. [识别解析的逻辑](#-识别解析的逻辑) 1. [识别的逻辑](#-识别的逻辑) 2. [解析的逻辑](#-解析的逻辑) <!-- /code_chunk_output --> ------- # 类的关系 recogn-parse 包含以下几个主要类: - `RecognParse`:识别解析,是用户直接操作的主类,提供了完整的 `识别-解析` 机制。 - `Recognizer`:识别器。负责识别操作,所有的识别逻辑都是由该类来完成的。 - `Resolver`:解决者。负责解析操作,所有的解析逻辑都是由该类来完成的。 它们之间的关系如下图: ![识别解析_时序图][] # 识别解析的逻辑 当需要对目标 `target` 进行识别并解析时,可以调用以下任一方法: - `recognParse.resolve(target)` - `recognParse.resolveAsync(target)` **识别解析的逻辑步骤如下:** 1. 对目标 `target` 进行识别:这一步的目的是识别出目标 `target` 的类型 `type` 1. 前置识别:如果没有前置鉴定者,则跳过此步;否则,依次执行前置鉴定者列表中的鉴定者,直到 鉴定者成功识别出 `target` 的类型 `type` 或者 前置鉴定者列表中的鉴定者执行完毕(详见下图 `对鉴定者列表执行识别`); 2. 识别:如果指定了鉴定者的名字,则直接执行对应的鉴定者;否则,将依次执行鉴定者列表中的鉴定者,直到 鉴定者成功识别出 `target` 的类型 `type` 或者 前置鉴定者列表中的鉴定者执行完毕(详见下图 `对鉴定者列表执行识别`); 3. 后置识别:如果没有后置鉴定者,则跳过此步;否则,依次执行后置鉴定者列表中的鉴定者,直到 鉴定者成功识别出 `target` 的类型 `type` 或者 后置鉴定者列表中的鉴定者执行完毕(详见下图 `对鉴定者列表执行识别`); 4. 经过以上几步,如果最后一步没有返回的识别结果,则终止程序;否则,继续下一步; 2. 对目标 `target` 进行解析:依次对每个识别出来的类型执行以下步骤: 1. 如果没有对应类型的解析器,则跳过些类型的解析;否则,继续; 2. 前置解析:如果没有前置解析函数,则跳过此步;否则,依次执行前置解析函数列表中的所有函数,并忽略执行解析函数时抛出的异常; 3. 解析:获取对应类型的解析器,并执行该解析器; 4. 后置解析:如果没有后置解析函数,则跳过此步;否则,依次执行后置解析函数列表中的所有函数,并忽略执行解析函数时抛出的异常; 5. 将以上几步中最后一步的解析结果视作该类型的解析结果; 3. 汇总每个类型的识别结果和解析结果,并返回; **流程图如下:** ![识别解析_活动图][] ![对鉴定者列表执行识别][] 其中 `鉴定者` 分为两类: - `鉴定函数`:类型为 `type Judge<Options = any> = (target: any, targetOptions: Options, preResult: FormatJudgeResult) => JudgeReturn`,用于鉴定 target 的类型 和 格式化数据,如果返回 空,表示鉴定失败,参数如下: * @param `target` - 目标 * @param `targetOptions` - 目标相关的选项 * @param `preResult` - 上一个鉴定函数的鉴定结果 * @returns 返回鉴定结果,可以是异步的鉴定结果;鉴定结果是可以是 一个 或 一组 鉴定信息 {@link JudgeInfo},也可以是空,如果是空 表示鉴定失败 - `串行鉴定者`:类型为 `type SerialJudger<Options = any> = Judge<Options>[]` 串行鉴定者就是一组鉴定函数,所有的鉴定函数都会依次执行,不论中间有没有失败,都会依次执行完所有的鉴定函数,并会以最后一个鉴定函数返回的结果为最终的鉴定结果。 * 串行鉴定者序列中的任何项识别失败都不会中止 串行鉴定者序列 的执行。即:即使 串行鉴定者序列 `SerialJudger` 中的某一个 `Judge` 返回 null 或者 抛出错误,则仍会执行此 串行鉴定者序列 SerialJudger 中的下一个 Judge **鉴定者的执行流程如下:** ![执行鉴定者][] `解析器`也分为两类: + `解析函数`:类型为 `type Parse<Options = any> = (target: any, targetOptions: Options, preResult: any, recognResult: JudgeInfo) => any`,用于对 target 进行解析,参数如下: * @param `target` - 目标 * @param `targetOptions` - 目标相关的选项 * @param `preResult` - 之前的解析结果 * @param `recognResult` - 识别结果 * @returns 解析的结果 + `串行解析器`: 类型为 `type SerialParser<Options = any> = Parse<Options>[]`,串行解析器就是一组解析函数,这些解析函数会依次执行,并会以最后一个解析函数返回的结果为最终的解析结果。这组解析函数中如果有解析函数抛出错误,则会终止解决流程。 ## 识别的逻辑 每次执行识别操作时,会按照如下顺序调用鉴定者: 1. 依次执行前置鉴定者列表 `preJudgers` 中的鉴定者,如果有鉴定成功的,则会停止后续的前置鉴定者的执行,并将鉴定结果 传给后续流程。 2. 如果提供了 `name`,则会在 命名的鉴定者 中查找 `name` 对应的鉴定者,然后执行指定的鉴定者。然后 跳到 步骤 5。 3. 如果没有提供 `name`,则会执行 匿名的鉴定者列表。如果有鉴定结果,则会 跳到 步骤 5。 4. 否则,则会执行 所有的命名鉴定者。如果有鉴定结果,则会 跳到 步骤 5。 5. 依次执行后置鉴定者列表 `postJudgers` 中的鉴定者,如果有鉴定成功的,则会停止后续的后置鉴定者的执行,并返回 鉴定结果。否则返回 空; ![识别][] ![对鉴定者列表执行识别][] ![执行鉴定者][] ## 解析的逻辑 每次执行解决操作时,会按照如下顺序调用解析器: 1. 如果找不到对应类型 type 的 解析器,则会终止解决流程。 2. 依次执行前置解析器 `preParses` 中的所有解析函数,即使有抛出错误,也会继续执行,并会以最后一个解析函数返回的结果为最终前置解析器的解析结果,然后将 前置解析的结果 传给后续的解析器。 3. 依次执行根据 类型 type 查找到的解析器序列。如果序列中任意解析器抛出错误,则会终止解决流程。否则,以最后一个解析函数返回的结果为最终的解析结果 并 传递给后续的解析器。 4. 依次执行后置解析器 `postParses` 中的所有解析函数,即使有抛出错误,也会继续执行,并会以最后一个解析函数返回的结果为最终的解析结果。 ![解决][]