從 Writing a simple lexer in PHP 找到了一個很不錯的詞語分析教學,
實際上就是最近在做 Avane 正式版,然後需要分析模板標籤,
原本想說單純的 RegEx 就足夠了,但是看看之前寫的非正式版 Avane
好像還 .. 可以啦(?)
但是後來想說沒試過 Lexer,那就來試試看好了,畢竟現在不趕快摸,之後可沒有時間啊喂wwww
(按下閱讀更多來詳細閱讀)
逐漸理解
在理解 Lexer 的時候我翻了大概至少 30 個文件左右,畢竟 Lexer 是一個「詞語分析」
而不是屬於PHP 的「一種寫法」,所以其實沒辦法用現有概念去理解這個東西,
之後在別人的 Github Issue 上找到了一個片段:
recoursive parser using implicit tokens ignore white space lexer rule #239
看了之後大概明白這種東西其實就是讓任何字都具有意義。
例如一句:<?php echo “Hello"; ?>
就會像是:「開始符號 函式 雙引號 字串 雙引號 分號 結束符號」這種感覺。
之後開始修改範例成為自己的產物
如果這世界上沒有範例這種東西,我看整個 TeaMeow 都要死一半了,
這張圖片其實就是簡易版的詞語分析,不過現在還有優先順序的問題,
例如「if」如果在「elseif」的前面,那麼「elseif」就會變成「else」「if」。
記住是意義優先
「?」這個問號,其實我在詞語分析裏寫成「T_SECONDARY_SEPARATOR」,
中文則是「次要分隔符號」而不是直接寫成「T_QUESTION_MARK」(問號),
主要原因是因為我認為不應該直接按照符號的表面去定義他的意思,
畢竟,詞語分析嘛。
分析完所有詞語之後,就是整合
在我的詞語中有兩個主要用來分析是不是我要的標籤:
「T_OPEN_TAG(起始標籤)」、「T_CLOSE_TAG(結束標籤)」
其實就像是「<?php」和「?>」這兩個標籤,所以我做了一個迴圈,
會從「起始標籤」開始收集接下來的詞語,
直到遇見「結束標籤」,然後就把這一個群組丟到一個陣列,順便收集長度跟內容還有位置和行數,
然後開始尋找下一個「起始標籤」,接著重複,
不過現在只做到這裡,接下來大概就是去分析個別群組了吧。