[인터넷]브라우저의 작동 원리(2) - 파싱과 DOM 트리 구축

1. 파싱 일반

1. 파싱이란?

  1. 파싱 : 문서 파싱은 브라우저가 코드를 이해하고 사용할 수 있는 구조로 변환하는 것을 의미
  2. 파싱 결과 : 보통 문서 구조를 나타내는 노드 트리, 파싱 트리(parse tree) 또는 문법 트리(syntax tree)라고 불림
  3. 예시 : 2+3-1과 같은 표현식은 다음과 같은 트리가 된다.

2. 파서 - 어휘 분석기 조합

파싱은 어휘 분석과 구문 분석이라는 두 가지로 구분

1. 어휘 분석과 구문 분석

  1. 어휘 분석 : 자료를 토큰(유효하게 구성된 단위의 집합체로 용어집, ex-사전에 등장하는 모든 단어 )으로 분해하는 과정
  2. 구문 분석 : 언어의 구문 규칙을 적용하는 과정

2. 파서가 하는일

  1. 어휘 분석기(=토큰 변환기) : 자료를 유효한 토큰으로 분해, 공백과 줄 바꿈 같은 의미 없는 문자를 제거
  2. 파서 : 아래의 과정을 반복하여 언어 구문 규칙에 따라 문서 구조를 분석함으로써 파싱 트리를 생성

    어휘 분석기로부터 새 토큰을 받아서 구문 규칙과 일치하는지 확인
    1. 규칙에 맞으면 : 규칙에 맞으면 토큰에 해당하는 노드가 파싱 트리에 추가되고 파서는 또 다른 토큰을 요청
    2. 규칙에 맞지 않으면 : 파서는 토큰을 내부적으로 저장하고 토큰과 일치하는 규칙이 발견될 때까지 요청, 맞는 규칙이 없는 경우 예외로 처리하는데 이것은 문서가 유효하지 않고 구문 오류를 포함하고 있다는 의미

변환

파싱트리는 최종 결과물이 아님, 이후에 변환 과정이 더 필요함
예시: 컴파일 과정 - 소스 코드를 기계 코드로 만드는 컴파일러는 파싱 트리 생성 후 이를 기계 코드 문서로 변환

3. 파서의 종류

  1. 하향식 파서 : 구문의 상위 구조로부터 일치하는 부분을 찾기 시작
  2. 상향식 파서 : 구문의 하위 구조로부터 일치하는 부분을 찾기 시작
    여기서는 하향식 파서와 상향식 파서에 대해서 더 자세히 다루지 않을 것입니다. 원하시는 분은 출처의 글로 가셔서 보시는걸 권장합니다.

2. HTML 파서

1. HTML 파서란?

  1. HTML 파서 : HTML 마크업을 파싱 트리로 변환
  2. 문법 정의 : 어휘와 문법은 W3C에 의해 명세로 정의, 현재는 HTML5
  3. 유연한 문법 : HTML은 암묵적으로 태그에 대한 생략이 가능, 가끔 시작 또는 종료 태그 등을 생략(XML과의 차이)
    따라서 HTML은 파싱하기 어렵고 전통적인 구문 분석이 불가능하기 때문에 문맥 자유 문법이 아니라는 것이다. XML 파서로도 파싱하기 쉽지 않음

2. DOM(Document Object Model)

  1. DOM(Document Object Model) : 문서 객체 모델의 줄임말
  2. 파싱 트리는 DOM의 요소와 속성 노드의 트리로서 출력 트리가 됨
  3. HTML 문서의 객체 표현이고 외부를 향하는 자바스크립트와 같은 HTML 요소의 연결 지점
  4. 트리의 최상위 객체는 문서
  5. DOM은 마크업과 1:1의 관계

    예시

    <html>
      <body>
       <p>Hello World</p>
       <div><img src="example.png" /></div>
      </body>
    </html>

    이러한 코드는 아래와 같은 DOM 트리로 변환 할 수 있음

3. 파싱 알고리즘

1. 하향식 파서와 상향식 파서 불가능

HTML은 일반적인 하향식 또는 상향식 파서로 파싱이 안됨

  • 언어의 너그러운 속성
  • 잘 알려져 있는 HTML 오류에 대한 브라우저의 관용
  • 변경에 의한 재파싱 ( 일반적인 소스는 파싱하는 동안 변하지 않지만 HTML에서 document.write을 포함하고 있는 스크립트 태그는 토큰을 추가할 수 있기 때문에 실제로는 입력 과정에서 파싱이 수정됨 )

2. HTML 파서

1. 토큰화 : 어휘 분석으로서 입력 값을 토큰으로 파싱

토큰을 인지해서 트리 생성자로 넘기고 다름 토큰을 확인하기 위해 다음 문자를 확인, 입력의 마지막까지 이 과정을 반복
(HTML에서 토큰은 시작 태그, 종료 태그, 속성 이름과 속성 값)

토큰 알고리즘 : 상태 기계(State Machine)
- 각 상태는 하나 이상의 연속된 문자를 입력받아 이 문자에 따라 다음 상태를 갱신, 그러나 결과는 현재의 토큰화 상태와 트리 구축 상태의 영향을 받는데. 이것은 같은 문자를 읽어 들여도 현재 상태에 따라 다음 상태의 결과가 다르게 나온다는 것을 의미
- 예제

<html>
  <body>
     Hello world
  </body>
</html>  

초기 상태 "자료 상태"
< 문자를 만나면 상태는 "태그 열림 상태"로 변함
a 부터 z까지의 문자를 만나면 "시작 태그 토큰"을 생성(생성되는 토큰 = html토큰), 상태는 "태그 이름 상태" 변함 (> 문자를 만날 때까지)
>문자에 도달 현재 토큰이 발행, 상태는 다시 "자료 상태"
/ 문자는 종료 태그 토큰을 생성

2. 트리 구축 알고리즘

  1. 파서가 생성되면 문서 객체가 생성
  2. 트리 구축이 진행 되는 동안 문서 최상단에서는 DOM 트리가 수정되고 요소가 추가됨
  3. 토큰화에 의해 발행된 각 노드는 트리 생성자에 의해 처리
  4. DOM 트리에 요소를 추가하는 것이 아니라면 열린 요소는 스택(임시 버퍼 저장소)에 추가, 이 스택은 부정확한 중첩과 종료되지 않은 태그를 교정
  5. 알고리즘은 상태 기계
  6. 상태는 삽입 모드

예제

<html>
  <body>
     Hello world
  </body>
</html>  

입력 값 토큰화 단계에서 만들어지는 일련의 토큰
"html" 토큰: "html 이전" 모드, 토큰은 이 모드에서 처리, HTMLHtmlElement 요소를 생성하고 문서 객체의 최상단에 추가, 상태는 "head 이전" 모드로 변경
"body" 토큰: "head" 토큰이 없더라도 HTMLHeadElement는 묵시적으로 생성되어 트리에 추가, body 토큰이 처리, HTMLBodyElement가 생성되어 추가, 상태는 "body 안쪽" 모드
"Hellow world" 문자열의 문자 토큰: 첫 번째 토큰이 생성되고 "본문" 노드가 추가, 다른 문자들이 그 노드에 추가
html 종료 태그: "body 다음 다음" 모드
마지막 파일 토큰: 파싱을 종료

3. 파싱이 끝난 이후의 동작

  1. 브라우저는 문서와 상호작용
  2. 문서 파싱 이후에 실행되어야 하는 "지연" 모드 스크립트를 파싱하기 시작
  3. 문서 상태는 "완료"
  4. "로드" 이벤트가 발생

출처
1.브라우저는 어떻게 동작하는가?

좋은 웹페이지 즐겨찾기