<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                解析器與舞臺劇 ============== 好吧, 這是一個單章. 語法解析和編譯原理是程序員的基礎科目, 筆者卻一直沒有學好. 看著語法樹跳來跳去的圈圈, 腦子里像有一群猴子在蹦跶. 一直想有機會補足這門功課, 為 TOML 寫個解析器是個不錯的選擇. 因此 tom-toml 的解析是純手工的. 作為一個新手筆者無法用正規準確的文字描述解析器的寫法和原理, 因此本章用舞臺劇來比喻解析器. 看官權當是看故事, 不必嚴格追究文法和用詞. 本文指的是類 [PEG][1] 的方法, 這里有一篇翻譯 [解析表達文法][2]. 簡單的說 PEG 下的一切都是可確定的, 無二義性, 上下文無關, 無回溯的(線性時間). 這讓我想到了舞臺劇(事實是, 我先寫完了 tom-toml 才發現用的是手工 PEG 的方法). 劇本是寫好的, 場景, 臺詞, 演員, 結果都是固定的. 那么讓我給你講個大導演 TOM 導演一出舞臺劇的故事. ## 湯姆的故事 吉它湖大劇院要辦一場舞臺劇, 這個任務當然是由大導演湯姆來做, 不然還有誰呢! 這天是周五下午三點, 湯姆接到了劇院下達的任務, 演一場舞臺劇. 看完任務, 湯姆怨念驟起: 啥事兒都找我, 舞臺劇反反復復都演了多少年了, 弄啥勒! 不中, 黑嘍還得去斗地主咧, 快下班兒了, 時間緊任務急, 倆鐘頭弄完它. 杰森, 把咱勒臨時演員都叫來, 有活兒了. 助理杰森抬起頭 老板兒, 撒子事兒么? 你快說, 上次那個劇本的大括弧還沒有寫完呢. 湯姆 你胡扯啥, 不是叫你叫臨時演員都來么! 杰森 沒得問題! 100 分鐘完成. 湯姆 拉到吧, 1 分鐘, 只給你 1 分鐘. 杰森扭頭大喊 湯姆要發福利了.... 殷特, 付樂得, 司瓊在劇院門口已經蹲守三個月了, 不然還能去哪兒呢! 臨時演員的職業操守就是等活兒和追討工資, 蹲守是基本功. 杰森的聲音讓三人眼睛一亮, 下一秒就出現在湯姆面前, 此刻杰森的脖子還處于180度狀態, 迷茫的望著門口. 我給恁仨說, 現在有個急活兒, 我直接念臺詞你們誰能演就言一聲兒 湯姆掰了掰手指頭 1 殷特和付樂得同時出聲 我認識1, 我能演 司瓊一臉漠然, 不懂啊. 湯姆傻眼了, 心說我正琢磨第一句說啥勒, 這倆伙當臺詞了, 算了, 我也懶的想了, 那就 1 吧, 這... 2 殷特和付樂得那個高興啊 2 我也認識, 我能演 湯姆有點不高興了, 這倆顯擺啥咧, 認識個1,2就這德性 點 殷特茫然了, 付樂得心里高興啊 點我也會, 我演吧 湯姆受不了了 12. 你都認識, 你學問不低啊, 不用說 12.3 你都認識了? 付樂得一拍胸脯 沒問題, 12.3 我認識, 12.34567 我也能演 湯姆拿了張紙, 畫個圈兒 中了, 這個角色給你了, 這是場次安排分劇本, 好好練練, 走吧 付樂得接分劇本扭頭走了 咱接著走臺詞啊, 下個臺詞是... " 司瓊其實是他們三個學歷最高的了, 研究生啊, 可惜書讀的太多, 腦子就傻了, 只知道照本宣科, 從小就知道劇本臺詞都是以 " 開始的, 不然那就不是臺詞啊, 終于讓瓊斯等到了 湯姆導演, 這個是臺詞, 我會 湯姆一頭黑線, 感情 12.3 就不是臺詞! 怒了 你啥意思, 我前面說了那么多, 那都不叫臺詞! 你@#%$#^%$&$%#@%$@#$ 瓊斯一聲不吭, 支起耳朵, 緊鎖眉頭把湯姆的每一個字都記下 你以為你會了可多, 你不就認識個" 瓊斯眉頭一展 嗯, 湯姆導演, 你說的臺詞真好, 可標準了, 我都記下了, 保證演好 湯姆張大嘴巴足足90分鐘才楞過神來 中, 就這吧, 給你拿好分劇本, 趕恁咧走吧 瓊斯雙手接過劇本, 鞠躬, 走人. 殷特急了 導演給我也安排個活兒吧, 我都認識 0123456789 呢 湯姆隨口說 那你就報開場倒計時吧 湯姆分了劇本, 忽略頭才轉回90度的杰森, 低頭看表. 5點, 湯姆嘴角一揚走出了辦公室. ## PEG PEG 的解析過程就像舞臺劇, 固定的臺詞(待解析的文本), 固定的演員(token), 固定場景下有固定的演員和臺詞, 并且固定的轉場. token 判定函數對得到的字符逐個判斷, 例如當順序流入 1234.567 直到字符 "4" 時, ItsInteger 和 ItsFloat 都認為可能認識這個 token, 都反饋 "可能是", SMaybe 狀態. 出現了 ".", ItsInteger 返回"不認識" SNot 狀態, ItsFloat 繼續返回 SMaybe. 后續的字符都完畢 ItsFloat 都可識別, 都返回 SMaybe. 最后 ItsFloat 拿到 EOF 后確認認識, 返回 "確定是" SYes 狀態. 識別 token 就是這么一個過程. 那么, 整個的解析流程就像舞臺劇的場景, 每個場景是清楚會出現哪些 token 的. 以 TOML 語法為例, 開始場景命名為 stageEmpty, 可允許出現的 token 包括: EOF 空文本也是允許的 Whitespace 白字符 NewLine 新行 LF,CR,LFCR,CRLF Comment # 注釋 TableName [tableName] ArrayOfTables [[arrayOfTableName]] Key 鍵名 注: 上面的次序有效率問題, 甚至是必須的次序才能實現或簡化代碼. 周知開始場景和結束場景是相同的, EOF 出現在stageEmpty 中是理所當然的. 如果沒有 token 被匹配, 那一定是語法錯誤. 如果匹配, 就進入下一個場景, 每個場景都有固定的 token 列表, 循環這個過程直到重回開始場景識別到 EOF. token 和場景變化可以這樣描述 stageEmpty EOF -> stageEnd Whitespace -> stageEmpty NewLine -> stageEmpty Comment -> stageEmpty TableName -> stageEmpty ArrayOfTables -> stageEmpty Key -> stageEqual stageEqual Whitespace -> stageEqual Equal -> stageValue stageValue Whitespace -> stageEqual ArrayLeftBrack -> stageArray String -> stageEmpty Boolean -> stageEmpty Integer -> stageEmpty Float -> stageEmpty Datetime -> stageEmpty stageArray Whitespace -> stageEqual ArrayLeftBrack -> stageArrayWho ArrayRightBrack-> stageArrayWho String -> stageStringArray Boolean -> stageBooleanArray Integer -> stageIntegerArray Float -> stageFloatArray Datetime -> stageDatetimeArray stageStringArray Whitespace -> stageStringArrayComma String -> stageStringArray ArrayRightBrack-> stageArrayPop stageStringArrayComma Whitespace -> stageStringArrayComma Comma -> stageStringArray ArrayRightBrack-> stageArrayPop 以此類推, 其中 為便于閱讀, 上述定義省略部分新行和注釋, 這不會影響理解. Array 是可嵌套的, stageArrayWho 有多種實現方法, 需要專門的篇幅描述. 本文不討論. stageStringArray 也受嵌套影響, 肯定不能這么簡單就得到 stageXxxxArray. 本文不討論. 如果某個 token 在解析時做不到驗證完整性, 可以放到生成 Toml 時再檢查. **注: 在本新手眼里 Array 的嵌套被當作左遞歸的一種, 理論上 PEG 要求消除左遞歸文法, 先手工硬編碼解決這問題吧.** 完全手工構造場景變化表是比較痛苦的, 可以把 token 匹配和文法合法性檢查分開, 減省 stage 的數量. 比如 stageStringArrayComma 就可以減省, 留給其他代碼處理. 你會發現不同語言實現的 PEG, 在表達式文法和用詞上甚至不一致. PEG 確實沒有規定確切文法用詞, PEG 關注的是解析中的邏輯關系. [1]: http://en.wikipedia.org/wiki/Parsing_expression_grammar [2]: http://article.yeeyan.org/compare/35225
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看