리스펙스 구문 참조입니다. 이 문서는 입력 전용 S-표현식 문법과 Core AST로의 결정적 정규화 규칙을 정의합니다. 실행 의미와 표준 라이브러리 동작은 범위 밖입니다.
범위: 입력 문법 + 정규화. 사용자 매크로/리더 확장은 허용되지 않습니다.
R5RS-compat토글이 일부 규칙을 조정합니다(정확한 목록은 전체 사양 참조).
0) 파일 헤더(선택)
;! lispex 1.1
;! compat: r5rs ; R5RS-compat 모드 활성화
1) 인코딩 / 공백 / 주석
- 인코딩: UTF‑8
- 공백: space, tab, CR, LF
- 주석: 한 줄
; ..., 블록#| ... |#(중첩 가능)
2) 토큰 & 리터럴
심벌(identifier)
대소문자 구분, 유니코드 허용. 개념적 정규식: [^()\[\]{}\s"';,]+`. 예약어는 바인딩 금지(아래 참조).
불리언
#t #f
숫자(입력형)
- 정수(10진):
0 | -?[1-9][0-9]* - 유리수:
p/q(분모 0 금지) - 실수:
-?[0-9]+(\.[0-9]+)?([eE][-+]?[0-9]+)?
문자 / 문자열
- 문자:
#\a,#\space,#\x03B1 - 문자열:
"..."— 이스케이프\" \\ \n \t \r \xHH;
리스트 / 점리스트 / 벡터 / 바이트벡터
- 리스트:
(a b c); 점리스트:(a b . c) - 벡터:
#(a b c) - 바이트벡터:
#u8(0 255 ...)
인용 계열(리더 축약)
'x ⇒ (quote x)
`x ⇒ (quasiquote x)
,x ⇒ (unquote x)
,@xs ⇒ (unquote-splicing xs)
3) 모듈 헤더(선택)
(module <name>
(export id ...)
(import <name> ...)
body ...)
<name>은 심벌 또는 점-경로(util.string)입니다. 이 표면 헤더에는 rename/only/except가 없습니다. 모듈 없는 파일도 허용됩니다.
참고: 이 헤더는 선택 사항이며 가이드에서는 사용하지 않습니다. 리스펙스는 변환기 기반이므로, 예제는 최소한의 최상위 폼만 사용합니다. 일부 도구는 변환 과정에서 이 헤더를 평탄화하거나 무시할 수 있습니다.
4) 예약어(키워드) — 바인딩 금지
quote quasiquote unquote unquote-splicing
lambda if begin set! define let let* letrec
cond case and or when unless do
values call-with-values
call/cc dynamic-wind
module export import
다음 사용자 매크로/리더 확장 사용 시 즉시 오류: define-syntax syntax-rules syntax-case let-syntax letrec-syntax #lang #;.
5) Core 폼 — 정규화 후 남는 형태
(lambda (formals) body+)
(if test then else)
(begin e1 ... en)
(set! id expr)
(define id expr)
(define (f params) body+) ; 정규화 시 define+lambda로 환원
(let ((id expr) ...) body+)
(letrec ((id expr) ...) body+)
(quote datum)
(quasiquote template) ; §10 전개 규칙 후 Core로 수렴
(values expr*)
(call-with-values producer consumer)
(call/cc proc)
(dynamic-wind before thunk after)
6) 파생 폼 — 결정적 정규화
함수 정의 설탕
(define (f a b) body...) ⇒ (define f (lambda (a b) body...))
let*
(let* ((x e1) (y e2) ...) body)
⇒ (let ((x e1)) (let* ((y e2) ...) body))
cond
(cond (t1 b1...) ... (else e...))
⇒ (if t1 (begin b1...)
(if t2 (begin b2...)
...
(begin e...)))
(=> 변형은 v1 미지원)
case (equal?로 서술)
(case key
((k11 k12 ...) b1...)
...
(else e...))
⇒ (let ((t key))
(if (equal? t k11) (begin b1...)
(if (equal? t k12) (begin b1...)
...
(begin e...))))
and / or
(and) ⇒ #t
(and e1) ⇒ e1
(and e1 e2 ... en) ⇒ (if e1 (and e2 ... en) #f)
(or) ⇒ #f
(or e1) ⇒ e1
(or e1 e2 ... en) ⇒ (let ((t e1)) (if t t (or e2 ... en)))
R5RS-compat 노트: ;! compat: r5rs 활성 시, 바이트벡터 표기와 일부 판별자/포트 세부 규칙이 R5RS 변형을 따릅니다.