rokdocs
v0.1

1.2. 어휘 구조

이 장에서는 문자 흐름이 토큰 흐름으로 바뀌는 큰 그림을 살펴봅니다. 각 토큰 종류의 세부 형식은 후속 문서에서 정의하므로, 여기서는 전체 윤곽만 잡고 가겠습니다.

token           ::= identifier
                  | keyword
                  | numeric_lit
                  | string_lit
                  | byte_string_lit
                  | char_lit
                  | sentinel_lit                  // true | false | none
                  | punctuation
whitespace      ::= space_char+
                  | line_comment
                  | block_comment
space_char      ::= U+0009 | U+000A | U+000B | U+000C | U+000D | U+0020
line_comment    ::= "//" <any char except line_terminator>* line_terminator
block_comment   ::= "/*" <any char>* "*/"          // recursive
shebang_line    ::= "#!" <any char except line_terminator>*   // first line only, see 1.2.3
line_terminator ::= U+000A | U+000D U+000A? | U+000D

1.2.1. 토큰

컴파일러의 어휘 분석기 (이하 렉서) 는 소스 파일을 읽어 토큰 흐름을 만듭니다. 이렇게 만들어진 토큰은 다음과 같은 종류로 나뉘어 있습니다.

종류예
식별자 (identifier)count, α, Δt
키워드 (keyword)let, if, fn
숫자 리터럴42, 3.14, 0xFF, 1_000
문자열 리터럴"hello", r"raw\n", f"x = {x}", b"bytes"
문자 리터럴'A', c'A'
진리값 / 센티넬 리터럴true, false, none
연산자 / 구두점+, ==, .., [, ;

각 종류의 정확한 형식 규칙은 이어지는 문서들에서 차례로 정의하겠습니다.

1.2.2. 공백

공백 문자는 토큰 사이의 구분자로만 의미를 가지며, 그 자체로는 토큰을 만들지 않습니다.

다음에 나오는 코드포인트들을 공백으로 인정합니다.

코드포인트이름
U+0009탭 (TAB)
U+000A줄바꿈 (LF)
U+000B수직 탭 (VT)
U+000C폼 피드 (FF)
U+000D캐리지 리턴 (CR)
U+0020스페이스

위 표에 포함되지 않은 유니코드 공백류 (U+00A0 NO-BREAK SPACE, U+200B ZERO WIDTH SPACE 등) 는 공백으로 인정하지 않습니다. 이들은 식별자나 문자열 안에서 일반 코드포인트로 등장할 따름입니다.

또한 들여쓰기는 의미를 갖지 않습니다. 따라서 Python 식의 의미 있는 들여쓰기는 도입하지 않습니다.

1.2.3. 주석

rok 은 한 줄 주석, 블록 주석, 문서 주석의 세 종류를 지원합니다. 파일 첫 줄의 shebang 줄은 주석처럼 무시합니다.

Shebang 줄

파일의 첫 줄 (BOM 뒤) 이 #! 로 시작하면 그 줄은 shebang 줄이며 주석처럼 무시합니다. 그래서 #!/usr/bin/env rok 을 담은 스크립트는 ./script.rok 으로 실행됩니다 (9.10.1). 예외는 #! 뒤의 첫 토큰이, 공백과 문서 주석이 아닌 주석을 지나, [ 인 경우입니다: 그러면 #! 는 내부 속성 (#![allow(unused)]) 을 시작합니다. 그 뒤의 줄에 있는 #! 는 shebang 줄이 아닙니다.

한 줄 주석

// 이 줄 끝까지 주석

// 부터 그 줄의 줄 종결자까지가 주석으로 인식됩니다. 다만 줄바꿈 자체는 주석에 포함되지 않습니다.

블록 주석

/* 여러 줄
   걸쳐서 */

/* 와 */ 사이가 주석이며, 중첩이 허용됩니다. 안쪽의 /*/*/ 쌍이 정확히 닫혀야 바깥쪽이 닫히는데 (Rust 와 같은 규칙), 이러한 규칙 덕분에 큰 코드 영역을 잠시 비활성화할 때 유용하게 쓸 수 있습니다.

/* 바깥
   /* 안쪽 */
   여전히 주석 */

문서 주석

문서 주석은 Rust 처럼 네 형태가 있습니다.

/// 외부 문서 주석 (뒤따르는 항목)
//! 내부 문서 주석 (둘러싸는 파일, 모듈, 함수)
/** 외부 블록 문서 주석 */
/*! 내부 블록 문서 주석 */
  • 한 줄 문서 주석은 줄 종결자까지입니다. /// text 는 #[doc = "text"] (표시 뒤의 공백 하나는 버림), //! text 는 #![doc = "text"] 입니다 (6.2.8). //// 로 시작하는 줄은 일반 주석입니다.
  • 블록 문서 주석은 짝이 맞는 */ 까지이며 블록 주석처럼 중첩됩니다. /**/, /***/, 그리고 /*** 로 시작하는 주석은 일반 주석입니다. 그 텍스트는 #[doc] / #![doc] 속성 하나입니다. 빈 첫 줄과 빈 마지막 줄은 버립니다. 주석이 여러 줄에 걸치고 첫 줄 뒤의 모든 줄이 선택적 공백과 * 로 시작하면 그 접두어를 지웁니다. 그다음 비어 있지 않은 줄들에 공통인 들여쓰기와 */ 앞의 공백을 지웁니다. 줄 바꿈은 LF 입니다.
  • 내부 문서 주석은 파일, 모듈 본체, 함수 본체의 시작에만 옵니다. 그 밖의 자리에서는 에러입니다.
  • 외부 문서 주석은 뒤따르는 항목을 설명합니다. 아무것도 설명하지 않는 것 (}, ), ] 앞이나 파일 끝) 은 에러이며, 함수 매개변수에 붙은 것도 에러입니다. 문, match arm, 구조체 리터럴 필드, tuple 필드, 식에 붙은 것은 어떤 도구도 간직하지 않으며 unused_doc_comments lint (6.2.9) 를 일으킵니다.
  • 미리 빌드한 패키지의 ROKHIR 인터페이스 텍스트 (9.4) 는 문서 주석을 보존합니다.

1.2.4. 컴파일러 출력

렉서의 출력은 토큰 흐름과 위치 정보로 구성됩니다. 이때 위치 정보는 소스 파일 의 진단 단위 규칙을 따릅니다.

이렇게 만들어진 출력이 다음 단계인 구문 분석기의 유일한 입력이 되며, 구문 분석기는 원본 소스를 다시 보지 않습니다.

GitHub에서 이 페이지 고치기