Skip to content

사양

ECMAScript® 2023 언어 사양는 자바스크립트 언어에 관한 모든 내용을 상세히 설명하므로, 누구나 자체 자바스크립트 엔진을 구현할 수 있습니다.

우리의 파서를 위해 다음 장들을 학습해야 합니다:

  • 제5장: 표기 규칙
  • 제11장: ECMAScript 언어: 소스 텍스트
  • 제12장: ECMAScript 언어: 어휘 문법
  • 제13~16장: 표현식, 문장, 함수, 클래스, 스크립트 및 모듈
  • 부록 B: 웹 브라우저용 추가적인 ECMAScript 기능
  • 부록 C: ECMAScript의 엄격 모드

사양 내부 탐색을 위한 안내:

  • 클릭 가능한 항목은 영구 링크를 가지며, 주소줄에서 앵커로 표시됩니다. 예: #sec-identifiers
  • 항목 위에 마우스를 올리면 툴팁이 나타나며, 참조를 클릭하면 해당 항목의 모든 참조를 볼 수 있습니다

표기 규칙

제5장 5.1.5 문법 표기를 읽어야 하는 부분입니다.

여기서 주의할 점은 다음과 같습니다:

재귀

이것은 문법에서 리스트가 어떻게 표현되는지를 보여줍니다.

인수목록 :
  대입식
  인수목록 , 대입식

javascript
a, b = 1, c = 2
^_____________^ 인수목록
   ^__________^ 인수목록, 대입식,
          ^___^ 대입식

를 의미합니다.

선택 사항

선택적 문법에 _opt_ 접미사를 사용합니다. 예를 들어,

변수선언 :
  바인딩 식별자 초기화값_opt

javascript
var binding_identifier;
var binding_identifier = Initializer;
                       ______________ 초기화값_opt

를 의미합니다.

매개변수

[반환][입력]은 문법의 매개변수입니다.

예를 들어

스크립트 본문 :
    문장목록[~반환, ~대기, ~반환]

는 스크립트 내에서 상위 수준의 반환, 대기, 반환을 허용하지 않음을 의미하지만,

모듈 항목 :
  임포트 선언
  내보내기 선언
  문장 요소목록[~반환, +대기, ~반환]

는 상위 수준의 대기를 허용합니다.

소스 텍스트

제11장 2절: 소스 코드 종류는 스크립트 코드와 모듈 코드 사이에 큰 차이가 있음을 알려줍니다. 또한 use strict 모드는 오래된 자바스크립트 동작을 허용하지 않아 문법을 더 명확하게 만듭니다.

스크립트 코드는 엄격하지 않으며, 스크립트 코드를 엄격하게 하려면 파일 상단에 use strict를 삽입해야 합니다. HTML에서는 <script src="javascript.js"></script>라고 작성합니다.

모듈 코드는 자동으로 엄격합니다. HTML에서는 <script type="module" src="main.mjs"></script>라고 작성합니다.

ECMAScript 언어: 어휘 문법

보다 깊이 있는 설명을 원한다면, ECMAScript 사양 이해하기에 대한 V8 블로그를 읽어보세요.

자동 세미콜론 삽입

이 섹션은 자바스크립트를 작성할 때 세미콜론을 생략할 수 있는 모든 규칙을 설명합니다. 모든 설명은 다음과 같이 요약됩니다.

rust
    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 함수는 적절한 위치에서 수동으로 호출되어야 하며, 예를 들어 문장의 끝에서:

rust
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))
}

INFO

이 섹션의 ASI 설명은 파서를 염두에 두고 작성되었습니다. 명확하게 언급되듯이 소스 텍스트는 왼쪽에서 오른쪽으로 파싱된다. 이는 파서를 다른 방식으로 작성하는 것을 거의 불가능하게 만듭니다. jsparagus의 저자는 이 점에 대해 여기에서 성토했습니다.

이 기능의 사양은 매우 고수준이며, 이상하게도 절차적인 방식("소스 텍스트가 왼쪽에서 오른쪽으로 파싱될 때, 토큰이 발견되면..."처럼, 마치 브라우저 이야기를 하는 것처럼). 내가 아는 한, 이 사양에서 파싱의 내부 구현 세부 사항에 대해 가정하거나 암시하는 유일한 장소입니다. 그러나 이와 같은 방식이 아니라면, ASI를 기술하는 것은 어렵습니다. :::

표현식, 문장, 함수, 클래스, 스크립트 및 모듈

구문 문법을 이해하는 데 시간이 걸리며, 그 후 이를 파서 작성에 적용해야 합니다.