一、為什么要使用到編譯器前端技術(shù)?
跨平臺(tái)模板需要根據(jù)不同的規(guī)則得到不同的展示結(jié)果,這就需要對(duì)數(shù)據(jù)進(jìn)行運(yùn)算。
一開始是考慮使用一門腳本語(yǔ)言來(lái)實(shí)現(xiàn)數(shù)據(jù)的運(yùn)算,如javascript通過(guò)嵌入的js引擎如QuickJS來(lái)執(zhí)行JS腳本語(yǔ)言達(dá)到數(shù)據(jù)運(yùn)算的結(jié)果。
但考慮到運(yùn)算表達(dá)式的要求沒(méi)有那么復(fù)雜,加之以前對(duì)編譯器前端技術(shù)的了解也沒(méi)有一個(gè)合適的場(chǎng)景去落地。剛好有這么一個(gè)契機(jī),就打算自己實(shí)現(xiàn)一個(gè)DSL來(lái)運(yùn)算模板中的動(dòng)態(tài)數(shù)據(jù)。
二、思路與原理
實(shí)現(xiàn)一個(gè)DSL有幾個(gè)步驟:
第一步: 詞法分析
第二步: 語(yǔ)法分析
第三步: 語(yǔ)義分析
在詞法分析的時(shí)候,需要用到一種叫 有限自動(dòng)機(jī) 的一個(gè)計(jì)算機(jī)模型。
它通過(guò)在不同狀態(tài)之間的遷移變換分析我們給定的字符串中的詞語(yǔ)(Token),將字符串按我們指定的規(guī)則切分成多個(gè)Token。
詞法分析完成之后,開始進(jìn)行語(yǔ)法分析。與詞法分析一樣,按我們指定的規(guī)則將一個(gè)或多個(gè)Token組合在一起形成一個(gè)一個(gè)的表達(dá)式。
比如加減乘除表達(dá)未,比較表達(dá)未,三目運(yùn)算表達(dá)式。通過(guò)指定運(yùn)算符之前的優(yōu)先級(jí)與左右結(jié)合優(yōu)先級(jí),最后生成一個(gè)樹,我們叫它抽象語(yǔ)法樹(AST). 通過(guò)對(duì)AST進(jìn)行深度優(yōu)先遍歷,得到最終表達(dá)式的結(jié)果。
當(dāng)前的DSL并不是一個(gè)完整的腳本語(yǔ)言,我們按需要實(shí)現(xiàn)特定的運(yùn)算功能即可。、
有了這些表達(dá)式,我們就可以實(shí)現(xiàn)數(shù)據(jù)的動(dòng)態(tài)計(jì)算綁定,但這還不夠。最基礎(chǔ)的版本至少還需要實(shí)現(xiàn)類似vue或者微信小程序中的for與if語(yǔ)句。
最終我們將呈現(xiàn)如下的DSL模板語(yǔ)言:
<View>
<Label id="label1" text="{{ a * b > 100 ? "a * b比100大" : "a * b比100小" }}">class="hljs-keyword"Label>
<Label id="label2" if="{{ a > b }}">class="hljs-keyword"Label>
<Label id="label3" for="item in items" text="item.name">class="hljs-keyword"Label>
class="hljs-keyword"View>
通過(guò)這個(gè)布局模板我們要得到什么樣的結(jié)果呢?
1.label1 標(biāo)簽中的text運(yùn)算得到最終顯示的結(jié)果,而a 與 b則是我們上下文中給定的變量或者是字典中的key
2.label2 通過(guò)計(jì)算if中的表達(dá)式得到此Label是否需要顯示
3.label3 則通過(guò)循環(huán)items得到多個(gè)標(biāo)簽
通過(guò)自定義DSL我們可以按我們自己的指定的規(guī)則來(lái)計(jì)算出想要的各種表達(dá)式了。
接下來(lái),我們就從第一步詞法分析開始吧。
-
數(shù)據(jù)
+關(guān)注
關(guān)注
8文章
7122瀏覽量
89356 -
JS
+關(guān)注
關(guān)注
0文章
78瀏覽量
18143 -
javascript
+關(guān)注
關(guān)注
0文章
522瀏覽量
53905
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論