其實咱們很明白「解析」到底作了什麼,說白了就一句話咯:「將源代碼轉化機器碼」。難道很差奇轉化這一流程中到底涉及到什麼環節嗎?node
首先,咱們展上述的那句話——「將源代碼轉化機器碼」。express
在瀏覽器中,大多數解析是文檔,整個過程就是努力將文檔轉化爲代碼能夠理解和使用的結構,對應輸出的結果是對應文檔結構的節點樹,咱們一般叫它爲解析樹或語法樹。瀏覽器
感受理解上可能還會有點問題,咱們舉個例子,解析 2 + 3 -1 這個表達式,經過解析會輸出這樣的語法樹:bash
整個解析過程都是基於文檔的語法規則去處理的,而每種能夠解析的格式都有肯定的語法,又由連續的單詞和語法規則組成,這樣的語法咱們叫作 context free grammer,而人類語言不屬於此類範疇(因此不不能用常規的解析技術)。這樣看來對應的解析仍是比較刻板的過程,只是匹配語法而後轉化的過程。post
那解析過程能夠分幾個階段呢?spa
解析過程分爲兩個階段 lexical analysis 和 syntax analysis 。翻譯
lexical analysis 階段:整個過程是將輸入的文檔,轉化有效的 tokens。這裏想將 tokens 理解爲人類語言中單詞。3d
syntax analysis階段:該階段就是將上階段的產物應用語法規則,產出語法樹。code
上述的過程是基於對應的載體做用的分別是詞法分析器(lexer)和解析器(parse)。cdn
詞法分析器:將輸入文檔轉化爲有效的標記,能識別和剔除無效的字符。
解析器:將有效的標記轉化解析樹。
整個解析過程是循環的,parse 會不斷向 lexer 索要 token,而後嘗試去尋找對應的語法規則去擊中,如擊中則將 token 對應的 node 節點添加到 parse tree 上;若沒有擊中,先保存到內部;而後繼續索要 token 去擊中語法,直到將全部的 token 所有與語法規則擊中爲止,若是沒有就引起異常,這說明文檔存在異常,因存在語法錯誤。
而解析爲語法樹並無完成將源代碼轉化爲機器碼的步驟,還差最後一步就是翻譯。而翻譯過程也是同時解析過程進行,能夠理解爲下面的流程圖:
詳細講一下開始的例子: 2 + 3 -1 表達式。該表達式包含整數、加號和減號。
而對應數學計算語法以下:
那解析一下表達式咯:匹配語法規則的第一個子串是 2,而根據第 5 條語法規則,這是一個項。匹配語法規則的第二個子串是 2 + 3,而根據第 3 條規則(一個項接一個運算符,而後再接一個項),這是一個表達式。下一個匹配項已經到了輸入的結束。2 + 3 - 1 是一個表達式,由於咱們已經知道 2 + 3 是一個項,這樣就符合「一個項接一個運算符,而後再接一個項」的規則。2 + + 不與任何規則匹配,所以是無效的輸入。
而在計算機中對應詞彙都是有正則表示,因此上述表達式的詞彙用正則表達爲:
INTEGER: 0|[1-9][0-9]*
PLUS: +
MINUS: -
複製代碼
由於大多數解析的語法符合 context free grammer ,因此採用 BNF (巴科斯範式)規則。BNF 是由約翰·巴科斯(John Backus)和彼得·諾爾(Peter Naur)首先引入的用來描述計算機語言語法的符號集。語法規則爲
<符號> ::= <使用符號的表達式>
複製代碼
上述例子可定義爲:
expression := term operation term
operation := PLUS | MINUS
term := INTEGER | expression
複製代碼
上述僅僅是解析的整個理論過程,而其載體即是解析器,那解析器有哪些種類呢?