Skill Wiki v0.1.0

Docs / reference / dsl

On this page

.prime DSL grammar

A small, hand-written grammar. 28 keywords (one per kind), 14 verb names as field identifiers, 6 punctuation classes. Comments use //.

Lexical structure

  • Keywords — the 28 atom kinds. Reserved.
  • Identifiers — atom names (PascalCase) and field names (kebab-case).
  • Atom IDs@scope/kind-kebab-name. Cross-Prime refs allowed.
  • Strings — double-quoted, \\-escapes for ", n, t.
  • Numbers — integers and decimals.
  • Booleanstrue, false.
  • Punctuation{ } [ ] : ,
  • Comments// to end of line.

BNF (sketch)

prime-file       ::= atom-decl*

atom-decl        ::= kind-keyword name "{" field* "}"

kind-keyword     ::= "fact" | "term" | "rule" | "method" | ... (28 kinds)

name             ::= [A-Z][A-Za-z0-9]*

field            ::= field-name ":" value

field-name       ::= [a-z][a-z0-9-]*           // kebab-case

value            ::= string | number | bool
                   | atom-id
                   | list
                   | object

string           ::= '"' (escaped-char | non-quote)* '"'
number           ::= integer | decimal
bool             ::= "true" | "false"
atom-id          ::= "@" scope "/" name-kebab
                     scope ::= [a-z][a-z0-9-]*
                     name-kebab ::= [a-z][a-z0-9-]*
list             ::= "[" (value ("," value)* ","?)? "]"
object           ::= "{" (field ("," field)* ","?)? "}"

Trailing commas

Allowed in lists and objects. The parser silently accepts [a, b, c,] so reordering edge lists doesn't churn diffs.

Field types per value

Field shapeExamples
stringstatement: "..."
numberconfidence: 0.99
boolverified: true
atom idrequires: [@my/term-x]
list of stringstags: ["fintech", "button"]
list of objectssteps: [{ action: "..." }]
nested objectcontract: { must-include: [...] }

Edge fields

The 14 edge verbs are recognised as field names. Their values are always lists of atom IDs.

requires:        [@my/term-x, @my/term-y]
validates-with:  [@my/source-rfc-1234]
contradicts:     [@my/anti-pattern-y]
see-also:        [@my/pattern-z]

Edge cases

  • Duplicate fields — last wins; L1 emits a warning.
  • Empty list — equivalent to omitting the field.
  • Empty object — invalid for kind-required fields.
  • Self-reference — an atom that references itself in requires is an L3 cycle.

Why a DSL?

YAML or JSON would have worked. We picked a thin DSL because:

  1. YAML's whitespace + 9 ways to write a string makes parser errors fragile.
  2. Atom IDs (@scope/name) get a dedicated lexical class — better error messages on typos.
  3. Reserved kind keywords are clearer than YAML's kind: rule with arbitrary other fields.