Skip to content
Back to skills

Prolog Dcg Mastery

ASecurity

Definite Clause Grammar (DCG) standards and advanced patterns. Use when parsing text, lexing tokens, building ASTs, generating binary/text output, handling lookahead without cuts, error recovery, and using pushback lists.

  • 4 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added October 1, 2026
ai-agentstestinggit

Works with

  • terminal

Security analysis

A100/100

Scanned October 1, 2026

npx -y skills add dougransom/prolog-agent-toolkit --skill prolog-dcg-mastery --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Prolog Dcg Mastery?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Prolog Dcg Mastery
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/dougransom-prolog-dcg-mastery/badge)](https://www.skillsdirectory.com/skills/dougransom-prolog-dcg-mastery)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: prolog-dcg-mastery
description: Definite Clause Grammar (DCG) standards and advanced patterns. Use when parsing text, lexing tokens, building ASTs, generating binary/text output, handling lookahead without cuts, error recovery, and using pushback lists.
---

# Definite Clause Grammar (DCG) Mastery Guidelines

Use this skill when designing grammars, tokenizers, parsers, abstract syntax tree (AST) generators, or sequence serializers in Prolog.

## 1. Core Syntax & Modules

Always include standard DCG libraries across engines:

- **Scryer Prolog**: Requires explicit module import:
  ```prolog
  :- use_module(library(dcgs)).
  :- use_module(library(charsio)).
  ```
- **SWI / Trealla / Tau**: Standard syntax built-in or provided via standard library.

### ISO DCG Export & Import Notation (`Name//Arity`)

When defining modules or importing DCG non-terminals, always use the ISO double-slash convention (`Name//Arity` where `Arity` is the number of explicit DCG rule arguments):

```prolog
% Exporting a DCG non-terminal in a module header:
:- module(json_parser, [
    json_value//1,   % DCG non-terminal with 1 argument (expands to json_value/3)
    json_object//1
]).

% Importing specific DCG non-terminals from another module:
:- use_module(json_parser, [
    json_value//1
]).
```

---

## 2. Bidirectional Parsing & Serialization

Structure DCG rules so they operate bi-directionally whenever possible:

```prolog
% Rule parses a sequence of digits to an integer or formats an integer to chars
integer_ast(N) -->
    digits(Ds),
    { Ds \= [], number_chars(N, Ds) }.

digits([D|Ds]) --> digit(D), digits(Ds).
digits([])     --> [].

digit(D) --> [D], { member(D, "0123456789") }.
```

---

## 3. Pure Lookahead & Pushback Lists

Avoid non-logical cuts (`!`) inside DCG rules. Use **Pushback Lists** (right-hand side context insertion `[X], ...`) to implement lookahead cleanly:

```prolog
% Lookahead: inspect next character C without consuming it
peek(C), [C] --> [C].

% Rule matching an identifier until a delimiter without consuming the delimiter
identifier([C|Cs]) -->
    [C],
    { char_type(C, alphanumeric) },
    !, % Local deterministic match
    identifier(Cs).
identifier([]) --> [].
```

---

## 4. AST Construction Patterns

Pass AST accumulator variables in rule arguments:

```prolog
expr(bin_op(Op, Left, Right)) -->
    term(Left),
    op(Op),
    expr(Right).
expr(Term) --> term(Term).

op(+) --> "+".
op(-) --> "-".
op(*) --> "*".
```

---

## 5. Token Streams & Parsing Pipeline

For complex programming languages or DSLs, split parsing into two pure DCG passes:

1. **Lexer Pass**: `phrase(tokens(Tokens), InputChars)`
2. **Parser Pass**: `phrase(ast(AST), Tokens)`

---

## 6. Higher-Order DCGs (`call//N`) & Meta-Predicates

Avoid duplicating DCG rules just to vary an element non-terminal or predicate. Use `call//N` to parameterize grammar rules, and declare `:- meta_predicate` with `//` or `2` so closures resolve in the caller module context:

```prolog
:- module(seq_combinators, [
    seq_of//2
]).

:- meta_predicate
    seq_of(?, //, ?, ?).

% Generic DCG rule to match a list of elements using a parameter non-terminal nonterm//1
seq_of([], _) --> [].
seq_of([X|Xs], NonTerm) -->
    call(NonTerm, X),
    seq_of(Xs, NonTerm).

% Example usage with lambda or defined non-terminal
% phrase(seq_of(Xs, \C^([C], { char_type(C, digit) })), "123")
```

---

## 7. Execution Safety & Testing

Test DCG grammars with `testing.pl` or `plunit`:

```prolog
test(parse_addition) :-
    phrase(expr(AST), "1+2"),
    AST == bin_op(+, num(1), num(2)).
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.