diff --git a/README.md b/README.md
index 21493c4..2fd1875 100644
--- a/README.md
+++ b/README.md
@@ -73,6 +73,7 @@ automatic, perfect-fidelity conversion between syntaxes.
## Additional resources
+ - [Preserves Expressions (P-expressions, pexprs)](preserves-expressions.html)
- Some [conventions for common data types](conventions.html)
- [Open questions](questions.html); see also the
[issues list]({{page.projectpages}}/issues)
diff --git a/_includes/cheatsheet-pexprs-plaintext.md b/_includes/cheatsheet-pexprs-plaintext.md
index 13c7108..e51b1da 100644
--- a/_includes/cheatsheet-pexprs-plaintext.md
+++ b/_includes/cheatsheet-pexprs-plaintext.md
@@ -1,22 +1,21 @@
-The definition of `Atom` is as given in the Preserves text syntax.
+The definitions of `Atom`, `ws`, and `linecomment` are as given in the Preserves text syntax.
```text
-Document := Expr* sp
-Expr := sp (Atom | Compound | Punct | Embedded | Annotated)
+Document := Expr* ws
+Expr := ws (SimpleExpr | Punct)
+SimpleExpr := Atom | Compound | Embedded | Annotated
Compound := Sequence | Record | Block | Group | Set
Punct := `,` | `;` | `:`+
-sp := (space | tab | cr | lf)*
-
-Sequence := `[` Expr* Trailer sp `]`
-Record := `<` Expr* Trailer sp `>`
-Block := `{` Expr* Trailer sp `}`
-Group := `(` Expr* Trailer sp `)`
-Set := `#{` Expr* Trailer sp `}`
+Sequence := `[` Expr* Trailer ws `]`
+Record := `<` Expr* Trailer ws `>`
+Block := `{` Expr* Trailer ws `}`
+Group := `(` Expr* Trailer ws `)`
+Set := `#{` Expr* Trailer ws `}`
Trailer := Annotation*
-Embedded := `#!` Expr
-Annotated := Annotation Expr
-Annotation := `@` Expr | `#` ((space | tab) linecomment) (cr | lf)
+Embedded := `#!` SimpleExpr
+Annotated := Annotation SimpleExpr
+Annotation := `@` SimpleExpr | `#` ((space | tab) linecomment) (cr | lf)
```
diff --git a/_includes/cheatsheet-pexprs.md b/_includes/cheatsheet-pexprs.md
new file mode 100644
index 0000000..f1e2763
--- /dev/null
+++ b/_includes/cheatsheet-pexprs.md
@@ -0,0 +1,23 @@
+The definitions of `Atom`, `ws`, and `linecomment` are as given in the Preserves text syntax.
+
+{:.postcard-grammar.textsyntax}
+| *Document* | := | *Expr*⋆ **ws**
+| *Expr* | := | **ws** (*SimpleExpr* | *Punct*)
+| *SimpleExpr* | := | *Atom* | *Compound* | *Embedded* | *Annotated*
+| *Compound* | := | *Sequence* | *Record* | *Block* | *Group* | *Set*
+| *Punct* | := | `,` | `;` | `:`+
+
+{:.postcard-grammar.textsyntax}
+| *Sequence* | := | `[` *Expr*⋆ *Trailer* **ws** `]`
+| *Record* | := | `<` *Expr*⋆ *Trailer* **ws** `>`
+| *Block* | := | `{` *Expr*⋆ *Trailer* **ws** `}`
+| *Group* | := | `(` *Expr*⋆ *Trailer* **ws** `)`
+| *Set* | := | `#{` *Expr*⋆ *Trailer* **ws** `}`
+
+{:.postcard-grammar.textsyntax}
+| *Trailer* | := | *Annotation*⋆
+
+{:.postcard-grammar.textsyntax}
+| *Embedded* | := | `#!` *SimpleExpr*
+| *Annotated* | := | *Annotation* *SimpleExpr*
+| *Annotation* | := | `@` *SimpleExpr* | `#` ((**space** | **tab**) *linecomment*) (**cr** | **lf**)
diff --git a/cheatsheet-plaintext.md b/cheatsheet-plaintext.md
index 8cbe30c..511d81a 100644
--- a/cheatsheet-plaintext.md
+++ b/cheatsheet-plaintext.md
@@ -6,6 +6,20 @@ title: "Preserves Quick Reference (Plaintext)"
Tony Garnock-Jones
{{ site.version_date }}. Version {{ site.version }}.
+These are non-normative "reference card" definitions. See also the normative [semantics]({{
+site.baseurl }}/preserves.html), [text syntax specification]({{ site.baseurl
+}}/preserves-text.html), and [machine-oriented syntax specification]({{ site.baseurl
+}}/preserves-binary.html), and the experimental [P-expressions definition]({{ site.baseurl
+}}/preserves-expressions.html).
+
+## Machine-Oriented Binary Syntax
+
{% include cheatsheet-binary-plaintext.md %}
+## Human-Oriented Text Syntax
+
{% include cheatsheet-text-plaintext.md %}
+
+## P-expression Syntax
+
+{% include cheatsheet-pexprs-plaintext.md %}
diff --git a/cheatsheet.md b/cheatsheet.md
index d1dd827..d04bd30 100644
--- a/cheatsheet.md
+++ b/cheatsheet.md
@@ -8,8 +8,9 @@ Tony Garnock-Jones
These are non-normative "reference card" definitions. See also the normative [semantics]({{
site.baseurl }}/preserves.html), [text syntax specification]({{ site.baseurl
-}}/preserves-text.html) and [machine-oriented syntax specification]({{ site.baseurl
-}}/preserves-binary.html).
+}}/preserves-text.html), and [machine-oriented syntax specification]({{ site.baseurl
+}}/preserves-binary.html), and the experimental [P-expressions definition]({{ site.baseurl
+}}/preserves-expressions.html).
## Machine-Oriented Binary Syntax
@@ -18,3 +19,7 @@ site.baseurl }}/preserves.html), [text syntax specification]({{ site.baseurl
## Human-Oriented Text Syntax
{% include cheatsheet-text.md %}
+
+## P-expression Syntax
+
+{% include cheatsheet-pexprs.md %}
diff --git a/preserves-expressions.md b/preserves-expressions.md
index 595284c..f90e110 100644
--- a/preserves-expressions.md
+++ b/preserves-expressions.md
@@ -7,6 +7,7 @@ October 2023. Version 0.3.0.
[text syntax]: preserves-text.html
+**Experimental.**
This document defines a grammar called *Preserves Expressions*
(*P-expressions*, *pexprs*) that includes [ordinary Preserves text
syntax][text syntax] but offers extensions sufficient to support a Lisp-
@@ -49,8 +50,8 @@ a compound expression, special punctuation, an `Embedded` expression, or
an `Annotated` expression. The class `SimpleExpr` includes all of `Expr`
except special punctuation.
- Expr = ws (SimpleExpr | Punct)
- SimpleExpr = Atom | Compound | Embedded | Annotated
+ Expr = ws (SimpleExpr / Punct)
+ SimpleExpr = Atom / Compound / Embedded / Annotated
Embedded and annotated values are as in the text syntax, differing only
in that uses of `Value` are replaced with `SimpleExpr`.
@@ -58,6 +59,7 @@ in that uses of `Value` are replaced with `SimpleExpr`.
Embedded = "#!" SimpleExpr
Annotated = Annotation SimpleExpr
Annotation = "@" SimpleExpr / "#" [(%x20 / %x09) linecomment] (CR / LF)
+ linecomment = *
P-expression special punctuation marks are comma, semicolon, and sequences of one or more colons.