확장 배커스-나우르 표기법

컴퓨터 과학에서 **확장 배커스-나우르 표기법**(Augmented Backus–Naur form, **ABNF**)은 배커스-나우르 표기법(BNF)에 기반을 두지만 고유한 문법과 유도 규칙으로 구성된 메타 언어이다. ABNF의 동기 부여 원리는 양방향 통신 프로토콜로 사용될 언어의 형식 체계를 기술하는 것이다. 이 표기법은 인터넷 표준 68("STD 68", 대소문자 표기법은 원문 그대로)로 정의되며, 이는  였고, 종종 IETF 통신 프로토콜의 정의 언어로 사용된다.

는 를 대체한다. 는 대소문자를 구분하는 문자열 리터럴을 지정하기 위한 구문을 추가하여 이를 업데이트한다.

## 개요

[섬네일|alt=ABNF 문법 규칙의 ABNF 구문 다이어그램|ABNF 규칙의 ABNF [구문 다이어그램]]

ABNF 명세는 다음과 같이 작성된 유도 규칙의 집합이다.

여기서 rule은 대소문자를 구분하지 않는 비단말 기호이며, definition은 규칙을 정의하는 기호 시퀀스, 문서화를 위한 주석으로 구성되며, 캐리지 리턴과 줄 바꿈으로 끝난다.

규칙 이름은 대소문자를 구분하지 않는다: `<rulename>`, `<Rulename>`, `<RULENAME>`, `<rUlENamE>`는 모두 동일한 규칙을 참조한다. 규칙 이름은 글자로 시작하고 그 뒤에 글자, 숫자, 하이픈이 올 수 있다.

규칙 이름 주위에 꺾쇠 괄호(`<`, `>`)는 필요하지 않다(BNF와 달리). 그러나 규칙 이름을 구별하기 위해 산문에서 사용될 때는 규칙 이름을 구분하는 데 사용될 수 있다.

## 예시

확장 배커스-나우르 표기법(ABNF) 페이지에 제시된 (미국) 우편 주소 예시는 다음과 같이 지정될 수 있다.

```abnf
postal-address   = name-part street zip-part

name-part        = *(personal-part SP) last-name [SP suffix] CRLF
name-part        =/ personal-part CRLF

personal-part    = first-name / (initial ".")
first-name       = *ALPHA
initial          = ALPHA
last-name        = *ALPHA
suffix           = ("Jr." / "Sr." / 1*("I" / "V" / "X"))

street           = [apt SP] house-num SP street-name CRLF
apt              = 1*4DIGIT
house-num        = 1*8(DIGIT / ALPHA)
street-name      = 1*VCHAR

zip-part         = town-name "," SP state 1*2SP zip-code CRLF
town-name        = 1*(ALPHA / SP)
state            = 2ALPHA
zip-code         = 5DIGIT ["-" 4DIGIT]
```


## 단말 값

단말 기호는 하나 이상의 숫자 문자로 지정된다.

숫자 문자는 퍼센트 기호 `%`, 그 뒤에 진법(`b` = 이진법, `d` = 십진법, `x` = 십육진법), 그 뒤에 값 또는 값의 연결(`.`로 표시)로 지정될 수 있다. 예를 들어, 캐리지 리턴은 십진법으로 `%d13` 또는 십육진법으로 `%x0D`로 지정된다. 줄 바꿈이 뒤따르는 캐리지 리턴은 `%d13.10`으로 연결하여 지정할 수 있다.

리터럴 텍스트는 인용 부호(`"`)로 묶인 문자열을 사용하여 지정된다. 이러한 문자열은 대소문자를 구분하지 않으며, 사용되는 문자 집합은 (미국)ASCII이다. 따라서 문자열 `"abc"`는 "abc", "Abc", "aBc", "abC", "ABc", "AbC", "aBC", "ABC"와 일치한다. RFC 7405는 대소문자 구분 문자열을 위한 구문을 추가했다: `%s"aBc"`는 "aBc"와만 일치한다. 그 이전에는 대소문자 구분 문자열은 개별 문자를 나열하는 방식으로만 지정할 수 있었다: "aBc"와 일치하려면 정의는 `%d97.66.99`가 된다. 문자열은 `%i` 접두사를 사용하여 명시적으로 대소문자를 구분하지 않는 것으로 지정할 수도 있다.

## 연산자

### 공백 문자
공백 문자는 정의의 요소를 구분하는 데 사용된다. 공백이 구분 기호로 인식되려면 명시적으로 포함되어야 한다. 단일 공백 문자에 대한 명시적 참조는 `WSP`(선형 공백)이며, `LWSP`는 새 줄이 허용되는 0개 이상의 공백 문자를 위한 것이다. RFC5234의 `LWSP` 정의는 두 필드 사이에 구분 기호를 형성하기 위해 적어도 하나의 공백 문자가 필요하기 때문에 논란이 있다.

정의는 왼쪽 정렬된다. 여러 줄이 필요한 경우(가독성을 위해), 연속 줄은 공백으로 들여쓰기된다.

### 주석 달기
`; comment`

세미콜론(`;`)은 줄의 끝까지 이어지는 주석을 시작한다.

### 연결
`Rule1 Rule2`

규칙은 일련의 규칙 이름을 나열하여 정의될 수 있다.

"aba" 문자열과 일치시키기 위해 다음 규칙을 사용할 수 있다.
* 
* 
* 

### 대안
`Rule1 / Rule2`

규칙은 슬래시(`/`)로 구분된 대체 규칙 목록으로 정의될 수 있다.

규칙 fu 또는 규칙 bar를 수락하기 위해 다음 규칙을 구성할 수 있다.
* 

### 증분 대안
`Rule1 =/ Rule2`

규칙 이름과 정의 사이에 `=/`를 사용하여 규칙에 추가 대안을 추가할 수 있다.

규칙
* 
* 
* 
은 따라서 다음과 동등하다.
* 

### 값 범위
`%c##-##`

숫자 값의 범위는 하이픈(`-`)을 사용하여 지정될 수 있다.

규칙
* 
은 다음과 동등하다.
* 

### 시퀀스 그룹
`(Rule1 Rule2)`

요소는 정의에서 규칙을 그룹화하기 위해 괄호 안에 넣을 수 있다.

"a b d" 또는 "a c d"와 일치시키기 위해 다음 규칙을 구성할 수 있다.
* 

"a b" 또는 "c d"와 일치시키기 위해 다음 규칙을 구성할 수 있다.
* 
* 

### 가변 반복
`n*nRule`

요소의 반복을 나타내기 위해 `&lt;a&gt;*&lt;b&gt;element` 형식이 사용된다. 선택적 `&lt;a&gt;`는 포함될 최소 요소 수를 제공한다(기본값은 0). 선택적 `&lt;b&gt;`는 포함될 최대 요소 수를 제공한다(기본값은 무한대).

0개 이상의 요소를 위해서는 `*element`, 0개 또는 1개의 요소를 위해서는 `*1element`, 1개 이상의 요소를 위해서는 `1*element`, 2개 또는 3개의 요소를 위해서는 `2*3element`를 사용한다. 정규 표현식의 `e*`, `e?`, `e+`, `e{2,3}`와 유사하다.

### 특정 반복
`nRule`

명시적인 요소 수를 나타내기 위해 `&lt;a&gt;element` 형식이 사용되며, 이는 `&lt;a&gt;*&lt;a&gt;element`와 동등하다.

두 개의 숫자 자리를 얻으려면 `2DIGIT`를 사용하고, 세 개의 숫자 자리를 얻으려면 `3DIGIT`를 사용한다. (`DIGIT`는 아래 "핵심 규칙"에서 정의된다. 아래 예시에서 우편 번호도 참조하라.)

### 선택적 시퀀스
`[Rule]`

선택적 요소를 나타내기 위해 다음 구성이 동등하다.
* 
* 
* 

### 연산자 우선순위
다음 연산자들은 가장 강한 결합에서 가장 약한 결합으로 주어진 우선순위를 갖는다.
#문자열, 이름 형성
#주석
#값 범위
#반복
#그룹화, 선택적
#연결
#대안

연결 연산자와 함께 대체 연산자를 사용하는 것은 혼란스러울 수 있으며, 명시적인 연결 그룹을 만들기 위해 그룹화를 사용하는 것이 권장된다.

### 핵심 규칙

[섬네일|alt=핵심 규칙의 ABNF 구문 다이어그램|핵심 규칙의 ABNF [구문 다이어그램]]

핵심 규칙은 ABNF 표준에 정의되어 있다.

핵심 규칙 다이어그램에서 **CHAR2** 문자 세트가 **char-val**에 인라인되고 **CHAR3**가 RFC 명세의 **prose-val**에 인라인된다는 점에 유의하라. 여기서는 주 구문 다이어그램에서 명확성을 위해 이름이 지정되었다.

## ABNF 자체의 ABNF 표현

ABNF의 구문 자체는 다음과 같은 ABNF로 표현될 수 있다.

```abnf
rulelist       =  1*( rule / (*WSP c-nl) )

rule           =  rulename defined-as elements c-nl
                       ; continues if next line starts
                       ;  with white space

rulename       =  ALPHA *(ALPHA / DIGIT / "-")

defined-as     =  *c-wsp ("=" / "=/") *c-wsp
                       ; basic rules definition and
                       ;  incremental alternatives

elements       =  alternation *WSP

c-wsp          =  WSP / (c-nl WSP)

c-nl           =  comment / CRLF
                       ; comment or newline

comment        =  ";" *(WSP / VCHAR) CRLF

alternation    =  concatenation
                  *(*c-wsp "/" *c-wsp concatenation)

concatenation  =  repetition *(1*c-wsp repetition)

repetition     =  [repeat] element

repeat         =  1*DIGIT / (*DIGIT "*" *DIGIT)

element        =  rulename / group / option /
                  char-val / num-val / prose-val

group          =  "(" *c-wsp alternation *c-wsp ")"

option         =  "[" *c-wsp alternation *c-wsp "]"

char-val       =  DQUOTE *(%x20-21 / %x23-7E) DQUOTE
                       ; quoted string of SP and VCHAR
                       ;  without DQUOTE

num-val        =  "%" (bin-val / dec-val / hex-val)

bin-val        =  "b" 1*BIT
                  [ 1*("." 1*BIT) / ("-" 1*BIT) ]
                       ; series of concatenated bit values
                       ;  or single ONEOF range

dec-val        =  "d" 1*DIGIT
                  [ 1*("." 1*DIGIT) / ("-" 1*DIGIT) ]

hex-val        =  "x" 1*HEXDIG
                  [ 1*("." 1*HEXDIG) / ("-" 1*HEXDIG) ]

prose-val      =  "<" *(%x20-3D / %x3F-7E) ">"
                       ; bracketed string of SP and VCHAR
                       ;  without angles
                       ; prose description, to be used as
                       ;  last resort
```


## 문제점

RFC 5234는 LWSP 정의와 관련하여 다음과 같은 경고를 추가한다.

## 각주

분류:형식 언어