항 확장
항 확장
정관절 문법(DCG)과 항 확장 관련 술어들을 설명해요.
본문
정관절 문법(Definite clause grammars)
정관절 문법은 문법 규칙을 표현하는 유용한 표기법이에요. 그러나 ISO 참조 표준은 이를 포함하지 않으므로 시스템 의존적 기능으로 간주해야 해요. 정관절 문법은 문맥 자유 문법의 확장이에요. 문법 규칙은 다음 형태예요:
head --> body.
-->는 미리 정의된 중위 연산자예요(8.14.10절). 정관절 문법의 몇 가지 특징:
- 비터미널(non-terminal) 기호는 어떤 callable 항이든 될 수 있어요.
- 터미널(terminal) 기호는 어떤 Prolog 항이든 될 수 있고 리스트로 쓰여져요. 빈 리스트는 빈 터미널 시퀀스를 나타내요.
- 시퀀스는 Prolog 연접 연산자(
','/2)로 표현돼요. - 문법 규칙의 머리는 비터미널 뒤에 선택적으로 터미널 시퀀스(즉 Prolog 리스트)가 따르는 형태예요.
- 문법 규칙의 본문은 비터미널, 터미널, 술어 호출, 이접(
;/2사용), if-then((->)/2사용) 또는 컷(!사용)의 시퀀스로 구성돼요. - 술어 호출은 중괄호(
{}/1사용)로 둘러싸야 해요. 이렇게 하면 추가 조건을 표현할 수 있어요.
문법 규칙은 Prolog 절의 "문법적 설탕(syntactic sugar)"에 불과해요. 각 문법 규칙은 터미널(토큰) 리스트를 입력으로 받아 이 리스트의 접두사를 파싱하고 이 리스트의 나머지(가능하면 확장된)를 출력으로 주어요. 이 나머지는 일반적으로 나중에 파싱돼요. 그래서 각 문법 규칙은 리스트를 명시적으로 관리하는 Prolog 절로 번역돼요. 두 인자가 추가돼요: 입력 리스트(Start)와 출력 리스트(End). 예를 들어:
p --> q.
는 다음과 같이 번역돼요:
p(Start, End) :- q(Start, End).
추가 인자를 제공할 수 있고 규칙의 본문은 여러 비터미널을 포함할 수 있어요. 예:
p(X, Y) -->
q(X),
r(X, Y),
s(Y).
는 다음과 같이 번역돼요:
p(X, Y, Start, End) :-
q(X, Start, A),
r(X, Y, A, B),
s(Y, B, End).
터미널은 통일을 사용해 번역돼요:
assign(X,Y) --> left(X), [:=], right(Y), [;].
는 다음과 같이 번역돼요:
assign(X,Y,Start,End) :-
left(X, Start, A),
A=[:=|B],
right(Y, B, C),
C=[;|End].
규칙의 왼쪽에 나타나는 터미널은 머리의 출력 인자에 연결돼요.
Prolog 술어에 대한 호출을 (비터미널과 구별하기 위해) 중괄호로 둘러싸 포함할 수 있어요:
assign(X,Y) --> left(X), [:=], right(Y0), {Y is Y0}, [;].
는 다음과 같이 번역돼요:
assign(X,Y,Start,End) :-
left(X, Start, A),
A=[:=|B],
right(Y0, B, C),
Y is Y0,
C=[;|End].
컷, 이접, if-then(-else)는 문자 그대로 번역돼요(중괄호로 둘러쌀 필요가 없음).
expand_term/2, term_expansion/2
Templates
expand_term(?term, ?term)
term_expansion(?term, ?term)
Description
expand_term(Term1, Term2)는 Term2가 Term1의 변환이면 성공해요. 변환 단계는 다음과 같아요:
Term1이 변수이면term_expansion(Term1, Term2)가 성공하면Term2와 통일되고Term2가Term1의 변환으로 간주.Term1이 DCG이면Term2는 그것의 번역(8.17.1절).- 그렇지 않으면
Term2는Term1과 통일.
term_expansion(Term1, Term2)는 사용자가 특정 변환을 정의할 수 있게 하는 훅(hook) 술어예요. GNU Prolog 컴파일러(4.4절)는 읽어 들인 각 Term1에 대해 expand_term/2를 자동으로 호출해요. 그러나 현재 릴리스에서는 컴파일러가 DCG 변환만 수행해요(즉 term_expansion/2를 사용할 수 없음). term_expansion/2를 사용하려면 expand_term/2를 명시적으로 호출해야 해요.
Errors: 없음.
Portability: GNU Prolog 술어.
phrase/3, phrase/2
Templates
phrase(?term, ?list, ?list)
phrase(?term, ?list)
Description
phrase(Phrase, List, Remainder)는 리스트 List가 문법 규칙 본문 Phrase가 정의하는 언어에 있으면 성공해요. Remainder는 구문(phrase)이 발견된 후 리스트에 남는 부분이에요.
phrase(Phrase, List)는 phrase(Phrase, List, [])와 동일해요.
Errors
Phrase가 변수 -instantiation_errorPhrase가 변수도 callable 항도 아님 -type_error(callable, Phrase)List가 리스트도 부분 리스트도 아님 -type_error(list, List)Remainder가 리스트도 부분 리스트도 아님 -type_error(list, Remainder)
Portability: GNU Prolog 술어.