Описание тега dcg
DCG (грамматики с определенными предложениями) - это компактный способ описания списков в Прологе.
DCG обычно связаны с прологом, но подобные языки, такие как mercury, также включают DCG. Их называют грамматиками с определенными предложениями, потому что они представляют грамматику как набор определенных предложений в логике первого порядка.
Праймер DCG от Маркуса Триска
Пролог и анализ естественного языка Фернандо К. Н. Перейра и Стюарт М. Шибер. примеры кода.
Изучите Пролог прямо сейчас! - Грамматики с определенными предложениями и другие грамматики с определенными предложениями
Некоторые интересные материалы доступны в виде пакетов SWI-Prolog, например
- dcg_util Майкла Хендрикса
- dcgutils Самера Абдаллаха
- dot_dcg, автор: Ли Кумбер
- pac от Кунаики Мукаи (продвинутый Пролог, не только DCG!)
- edgc от Peter Van Roy, Майкл Хендрикс
- а может еще какой.
Мне нравится думать о DCG как о практических грамматиках атрибутов.
Ссылки:
DCG обеспечивают абстракцию состояния потоковой передачи: не нарушайте ее
Примечание: при использовании DCG с SWI-Prolog помните о строковом типе и его синтаксисе в двойных кавычках.
Другими словами, многие примеры DCG здесь, в блогах и в статьях используют традиционное определение Пролога для двойных кавычек. Если вы возьмете такой код и будете использовать его с SWI-Prolog, он иногда выйдет из строя.
Чтобы избежать этой проблемы, есть флаги Пролога для изменения определения двойных и обратных кавычек.
Пример Prolog DCG, который устанавливает флаги Prolog.
:- module(course,
[ courses//1,
parse_courses/2
]).
:- [library(dcg/basics)].
:- set_prolog_flag(double_quotes, string).
:- set_prolog_flag(back_quotes, codes).
courses([Course|Courses]) -->
course(Course),
courses(Courses), !.
courses([]) --> [].
course(course(Course,Students)) -->
string_without("\n", Course_codes),
{ string_codes(Course,Course_codes ) },
"\n",
students(Students),
(
empty_line
;
[]
).
students([Student|Students]) -->
student(Student),
students(Students).
students([]) --> [].
student(Student) -->
spaces_or_tabs_plus,
(
(
string_without("\n",Student_codes),
{ string_codes(Student,Student_codes) },
"\n"
)
;
remainder(Student_codes),
{ string_codes(Student,Student_codes) }
).
spaces_or_tabs_plus -->
space_or_tab,
spaces_or_tabs_star.
spaces_or_tabs_star -->
space_or_tab,
spaces_or_tabs_star.
spaces_or_tabs_star --> [].
space_or_tab -->
(
"\s"
|
"\t"
).
empty_line --> "\n".
parse_courses(Codes,Courses) :-
DCG = courses(Courses),
phrase(DCG,Codes,Rest),
assertion( Rest == [] ).
:- begin_tests(course).
:- set_prolog_flag(double_quotes, string).
:- set_prolog_flag(back_quotes, codes).
test(001) :-
Input = "\c
MATH2221\n\c
\t201000001\n\c
\t201000002\n\c
\n\c
MATH2251\n\c
\t201000002\n\c
\t201000003\n\c
\n\c
COMP2231\n\c
\t201000003\n\c
\t201000001\c
",
string_codes(Input,Codes),
parse_courses(Codes,Courses),
assertion( Courses ==
[
course("MATH2221",["201000001","201000002"]),
course("MATH2251",["201000002","201000003"]),
course("COMP2231",["201000003","201000001"])
]
).
:- end_tests(course).