콘텐츠로 이동

아키텍처

이 문서는 Biome의 일부 내부 요소와 프로젝트 내에서의 사용 방식에 대해 다룹니다.

구문 분석기 아키텍처는 rowan이라는 라이브러리의 내부 분기 기반으로 구성되어 있으며, 이 라이브러리는 그린 트리 및 빨간 트리 패턴을 구현합니다.

CST(실제 구문 트리)는 모든 프로그램 정보를 포함한 데이터 구조로, 추상 구문 트리(АST)와 매우 유사합니다. 여기에는 단순한 세부 사항까지 모두 포함됩니다.

트라이비아(Trivia)는 프로그램이 정상적으로 동작하기 위해 중요한 정보를 의미합니다:

  • 공백
  • 주석

트라이비아는 노드에 연결됩니다. 하나의 노드는 초기 트라이비아와 최종 트라이비아를 가질 수 있습니다. 왼쪽에서 오른쪽으로 코드를 읽을 때, 초기 트라이비아는 키워드 앞에 나타나고, 최종 트라이비아는 키워드 뒤에 나타납니다.

주요 트라이비아와 보조 트라이비아는 다음과 같이 구분됩니다:

  • 토큰/키워드까지의 모든 트라이비아(줄바꿈 포함)는 주요 트라이비아(leading trivia)로 간주됨;
  • 다음 줄바꿈까지의 모든 내용(줄바꿈 제외)은 보조 트라이비아(trailing trivia)로 간주됨;

다음은 자바스크립트 코드의 예제이며, // 주석 1은 토큰 ;의 최종 트라이비아이고, // 주석 2는 키워드 const로 이어지는 트라이비아입니다. 아래는 Biome가 표현하는 최소화된 CST 버전입니다:

const a = "foo"; // 주석 1
// 주석 2
const b = "bar";
...
1: [email protected] ";" [] [Whitespace(" "), Comments("// 주석 1")]
...
1: [email protected] "const" [Newline("\n"), Comments("// 주석 2"), Newline("\n")] [Whitespace(" ")]
3: [email protected] "" [] []

CST는 설계상 직접 접근할 수 없습니다. 개발자는 언어 문법에서 자동 생성되는 시리즈의 API를 통해 빨간 트리(붉은 트리)를 이용해 정보를 읽을 수 있습니다.

오류에 강건하고 복원 가능한 구문 분석기

섹션 제목: “오류에 강건하고 복원 가능한 구문 분석기”

CST를 생성하려면 구문 분석기가 오류에 강건하고 복원 가능해야 합니다:

  • 강건성: 언어의 구문 오류를 발견한 후에도 분석을 재개할 수 있는 구문 분석기;
  • 복원 가능성: 오류 발생 위치를 이해하고, 정확한 정보를 생성하여 구문 분석을 재개할 수 있는 구문 분석기;

복원 가능성은 과학적인 규칙이 아니라, 어떤 상황에서든 분석기가 원래 분석 중이던 내용과 오류 발생 지점에 따라 예상대로 복원될 수 있다는 의미입니다.

또한 구문 분석기는 잘못된 구문을 소비하는 것을 막기 위해 ‘거짓 노드’(bogus nodes)를 사용합니다. 이러한 노드는 구문 오류로 인해 손상된 코드를 장식하는 데 사용됩니다.

다음 예시에서는 while 문의 괄호가 누락되어 있지만, 구문 분석기는 올바르게 복원되며 적절한 CST로 코드를 표현할 수 있습니다. 괄호와 반복 조건은 누락되었음을 표시하고, 코드 블록은 올바르게 분석됩니다:

while {}
JsModule {
interpreter_token: missing (optional),
directives: JsDirectiveList [],
items: JsModuleItemList [
JsWhileStatement {
while_token: [email protected] "while" [] [Whitespace(" ")],
l_paren_token: missing (required),
test: missing (required),
r_paren_token: missing (required),
body: JsBlockStatement {
l_curly_token: [email protected] "{" [] [],
statements: JsStatementList [],
r_curly_token: [email protected] "}" [] [],
},
},
],
eof_token: [email protected] "" [] [],
}

이것은 구문 분석 단계에서 발생한 오류입니다:

main.tsx:1:7 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ '('이 필요하지만 '{'를 찾았습니다
> 1 │ while {}
│ ^
ℹ {를 제거하세요

다음 코드 조각은 다르게 처리됩니다. 구문 분석기는 복원 단계에서 구문 구조를 올바르게 이해할 수 없으므로, 거짓 노드를 활용하여 일부 구문을 잘못된 것으로 표시해야 합니다. 여기서 JsBogusStatement를 주목하세요:

function}
JsModule {
interpreter_token: missing (optional),
directives: JsDirectiveList [],
items: JsModuleItemList [
TsDeclareFunctionDeclaration {
async_token: missing (optional),
function_token: [email protected] "function" [] [],
id: missing (required),
type_parameters: missing (optional),
parameters: missing (required),
return_type_annotation: missing (optional),
semicolon_token: missing (optional),
},
JsBogusStatement {
items: [
[email protected] "}" [] [],
],
},
],
eof_token: [email protected] "" [] [],
}

이렇게 분석 단계에서 얻는 오류는 다음과 같습니다:

main.tsx:1:9 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ 함수 선언에서 함수 이름이 필요하지만, 아무것도 찾지 못했습니다
> 1 │ function}
│ ^

Biome는 작업을 실행하기 위해 서버-클라이언트 아키텍처를 사용합니다.

디몬은 배경에서 수행되는 장시간 실행 서버로, Biome는 편집기와 CLI의 요청을 처리하기 위해 이를 생성하고 사용합니다.