duangsuse::Echo
583 subscribers
4.12K photos
118 videos
579 files
6.13K links
import this:
美而不丑、明而不暗、短而不凡、长而不乱,扁平不宽,读而后码,行之天下,勿托地上天国。
异常勿吞,难过勿过,叹一真理。效率是很重要,盲目最是低效。
简明是可靠的先验,不是可靠的祭品。
知其变,守其恒,为天下式;穷其变,知不穷,得地上势。知变守恒却穷变知新,我认真理,我不认真。

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): https://WOJS.org/#/
Download Telegram
#js #dom #parsing 提问: DOM 里如何拿到 <h1>~<h6> 标题树?
假设所有 heading 都在 document.body.children

和解析 #Python, yaml 的缩进实质相同,我给两种方法(递归层宽、Int栈循环)
输出类似 ["# a", e2, e3, ["## b", ee2], e5] 这种
算法对输入数据的抽象有点问题,关键点两个:
1. 何时解析一个子节点(上面 "## b")
2. 获取头部深度及建设每层 [head, *items] 的函数

和 Python 解析的主要区别在于:
1. 在解析非 <hN> 项时不需要取其深度
2. 没有 : 后无换行的“单行简写”(可选 : layout) 的说法
但是我们仍然会写兼容 Python 缩进解析的代码,用抽象层掩盖 DOM 的对非 <hN> 元素深度(因无此概念)的不处理。

畸形的基础抽象:
var lastHDepth = 0/*当前文段层深度*/;
const RE_HTAG = /H(\d+)/g
, isHeading=(e) => RE_HTAG.test(e.tagName)
, getHeadingDepth=(e) => { var n=parseInt(RE_HTAG.exec(e.tagName)[1]); lastHDepth=n+1; return n; }
, getElementDepth=(e) => lastHDepth;
实现的一些细节:
0. 实现最大的要点是:仅需过一遍,但内部元素皆可能“跌破”两层嵌套,需要级联化处理层结束的逻辑、终末项的实际属从层;
此外第一层是特殊的——它无需 heading 开头,但内部模式和前者一致。
1. 建设每层子树结构不需要提供函数值,统一存储形式允许完后重赋值即可
2. 可以提供 onXXX() 函数值检查缩进深度步进是否合法
递归层宽: #js #code
(补充:算法我都写出来了,调试了很久,待会贴链接)

Int栈算法:
其实就是比较骚的循环显式栈化重写

本身也不是什么复杂的算法(真正“复杂”的在于如何设计高性能、易组合的复用架构),分词器层面处理就只能用栈,然后业界主流实现是转化成 internal 的 END 词条然后交给 yacc 一样的状态机,把嵌套结构解析第二遍。
老ParserKt 的实现是 LayoutPattern (不如 fastparse 的 " ".rep(indent+1).map(_.len).flatMapX(new Layout(i).factor.rep(1, sep = ("\n"+" "*i))
)
方便),写第一遍看起来易用性还不好;当然,这是个泛用 #algorithm ,功能根本不止解析人类易读嵌套结构。
以上
deep.html
2.1 KB
#HTML #code #parsing #algorithm 本以为很快就行的,结果想了半天调试了半天😂,最后一个不是因为十进制移位和数据视口费时,反而是 tailcall 循环忘了加 return,真是眼高手低啊