規範
ECMAScript® 2023 語言規範 詳細說明了 JavaScript 語言的所有內容,因此任何人都可以實作自己的 JavaScript 引擎。
為了我們的解析器,以下章節需要研讀
- 第 5 章:符號約定
- 第 11 章:ECMAScript 語言:原始文字
- 第 12 章:ECMAScript 語言:詞法語法
- 第 13 - 16 章:表達式、語句、函式、類別、腳本和模組
- 附錄 B:網頁瀏覽器的其他 ECMAScript 功能
- 附錄 C:ECMAScript 的嚴格模式
為了在規範內導覽
- 任何可點擊的內容都有永久連結,它們在 URL 上顯示為錨點,例如
#sec-identifiers
- 將滑鼠懸停在項目上可能會顯示工具提示,點擊
References
會顯示其所有參考文獻
符號約定
第 5.1.5 章 語法符號 是我們需要閱讀的章節。
這裡需要注意的事項是
遞迴
這是在語法中呈現列表的方式。
ArgumentList :
AssignmentExpression
ArgumentList , AssignmentExpression
表示
a, b = 1, c = 2
^_____________^ ArgumentList
^__________^ ArgumentList, AssignmentExpression,
^___^ AssignmentExpression
可選
可選語法的 _opt_
後綴。 例如,
VariableDeclaration :
BindingIdentifier Initializer_opt
表示
var binding_identifier;
var binding_identifier = Initializer;
______________ Initializer_opt
參數
[Return]
和 [In]
是語法的參數。
例如
ScriptBody :
StatementList[~Yield, ~Await, ~Return]
表示在腳本中不允許頂層 yield、await 和 return,但
ModuleItem :
ImportDeclaration
ExportDeclaration
StatementListItem[~Yield, +Await, ~Return]
允許頂層 await。
原始文字
第 11.2 章 原始碼類型 告訴我們,腳本程式碼和模組程式碼之間存在巨大差異。 並且有一個 use strict
模式,通過禁止舊的 JavaScript 行為使語法更合理。
腳本程式碼 不是嚴格的,use strict
需要插入到檔案的頂部以使腳本程式碼變成嚴格模式。在 HTML 中,我們寫 <script src="javascript.js"></script>
。
模組程式碼 會自動處於嚴格模式。在 HTML 中,我們寫 <script type="module" src="main.mjs"></script>
。
ECMAScript 語言:詞法語法
如需更深入的解釋,請閱讀 V8 部落格上的 了解 ECMAScript 規格。
自動分號插入
本節描述了在編寫 JavaScript 時可以省略分號的所有規則。 所有解釋都歸結為
pub fn asi(&mut self) -> Result<()> {
if self.eat(Kind::Semicolon) || self.can_insert_semicolon() {
return Ok(());
}
let range = self.prev_node_end..self.cur_token().start;
Err(SyntaxError::AutoSemicolonInsertion(range.into()))
}
pub const fn can_insert_semicolon(&self) -> bool {
self.cur_token().is_on_new_line || matches!(self.cur_kind(), Kind::RCurly | Kind::Eof)
}
asi
函式需要在適用的地方手動呼叫,例如在語句的結尾
fn parse_debugger_statement(&mut self) -> Result<Statement<'a>> {
let node = self.start_node();
self.expect(Kind::Debugger)?;
self.asi()?;
self.ast.debugger_statement(self.finish_node(node))
}
資訊
關於 asi 的本節是從解析器的角度編寫的,它明確指出原始文字是從左到右解析的,這使得幾乎不可能以任何其他方式編寫解析器。 jsparagus 的作者在這裡對此發表了咆哮 這裡。
此功能的規範既是高階的,又是奇怪的程序性(“當從左到右解析原始文字時,遇到一個令牌...”,好像該規範正在講述一個關於瀏覽器的故事。據我所知,這是規範中唯一假設或暗示解析內部實作細節的地方。) 但很難用其他方式指定 ASI。
表達式、語句、函式、類別、腳本和模組
需要一段時間才能理解語法語法,然後將它們應用於編寫解析器。