mirror of
https://github.com/ocaml-tracing/ocaml-trace.git
synced 2026-03-09 12:23:32 -04:00
39 lines
No EOL
25 KiB
HTML
39 lines
No EOL
25 KiB
HTML
<!DOCTYPE html>
|
||
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Sexp_grammar (sexplib0.Sexplib0.Sexp_grammar)</title><link rel="stylesheet" href="../../../_odoc-theme/odoc.css"/><meta charset="utf-8"/><meta name="generator" content="odoc 2.2.2"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><script src="../../../highlight.pack.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body class="odoc"><nav class="odoc-nav"><a href="../index.html">Up</a> – <a href="../../index.html">sexplib0</a> » <a href="../index.html">Sexplib0</a> » Sexp_grammar</nav><header class="odoc-preamble"><h1>Module <code><span>Sexplib0.Sexp_grammar</span></code></h1><p>Representation of S-expression grammars</p></header><div class="odoc-content"><p>This module defines a representation for s-expression grammars. Using ppx_sexp_conv and <code>[@@deriving sexp_grammar]</code> produces a grammar that is compatible with the derived <code>of_sexp</code> for a given type.</p><p>As with other derived definitions, polymorphic types derive a function that takes a grammar for each type argument and produces a grammar for the monomorphized type.</p><p>Monomorphic types derive a grammar directly. To avoid top-level side effects, <code>[@@deriving sexp_grammar]</code> wraps grammars in the <code>Lazy</code> constructor as needed.</p><p>This type may change over time as our needs for expressive grammars change. We will attempt to make changes backward-compatible, or at least provide a reasonable upgrade path.</p><div class="odoc-spec"><div class="spec type anchored" id="type-grammar"><a href="#type-grammar" class="anchor"></a><code><span><span class="keyword">type</span> grammar</span><span> = </span></code><ol><li id="type-grammar.Any" class="def variant constructor anchored"><a href="#type-grammar.Any" class="anchor"></a><code><span>| </span><span><span class="constructor">Any</span> <span class="keyword">of</span> string</span></code><div class="def-doc"><span class="comment-delim">(*</span><p>accepts any sexp; string is a type name for human readability</p><span class="comment-delim">*)</span></div></li><li id="type-grammar.Bool" class="def variant constructor anchored"><a href="#type-grammar.Bool" class="anchor"></a><code><span>| </span><span><span class="constructor">Bool</span></span></code><div class="def-doc"><span class="comment-delim">(*</span><p>accepts the atoms "true" or "false", modulo capitalization</p><span class="comment-delim">*)</span></div></li><li id="type-grammar.Char" class="def variant constructor anchored"><a href="#type-grammar.Char" class="anchor"></a><code><span>| </span><span><span class="constructor">Char</span></span></code><div class="def-doc"><span class="comment-delim">(*</span><p>accepts any single-character atom</p><span class="comment-delim">*)</span></div></li><li id="type-grammar.Integer" class="def variant constructor anchored"><a href="#type-grammar.Integer" class="anchor"></a><code><span>| </span><span><span class="constructor">Integer</span></span></code><div class="def-doc"><span class="comment-delim">(*</span><p>accepts any atom matching ocaml integer syntax, regardless of bit width</p><span class="comment-delim">*)</span></div></li><li id="type-grammar.Float" class="def variant constructor anchored"><a href="#type-grammar.Float" class="anchor"></a><code><span>| </span><span><span class="constructor">Float</span></span></code><div class="def-doc"><span class="comment-delim">(*</span><p>accepts any atom matching ocaml float syntax</p><span class="comment-delim">*)</span></div></li><li id="type-grammar.String" class="def variant constructor anchored"><a href="#type-grammar.String" class="anchor"></a><code><span>| </span><span><span class="constructor">String</span></span></code><div class="def-doc"><span class="comment-delim">(*</span><p>accepts any atom</p><span class="comment-delim">*)</span></div></li><li id="type-grammar.Option" class="def variant constructor anchored"><a href="#type-grammar.Option" class="anchor"></a><code><span>| </span><span><span class="constructor">Option</span> <span class="keyword">of</span> <a href="#type-grammar">grammar</a></span></code><div class="def-doc"><span class="comment-delim">(*</span><p>accepts an option, both <code>None</code> vs <code>Some _</code> and <code>()</code> vs <code>(_)</code>.</p><span class="comment-delim">*)</span></div></li><li id="type-grammar.List" class="def variant constructor anchored"><a href="#type-grammar.List" class="anchor"></a><code><span>| </span><span><span class="constructor">List</span> <span class="keyword">of</span> <a href="#type-list_grammar">list_grammar</a></span></code><div class="def-doc"><span class="comment-delim">(*</span><p>accepts a list</p><span class="comment-delim">*)</span></div></li><li id="type-grammar.Variant" class="def variant constructor anchored"><a href="#type-grammar.Variant" class="anchor"></a><code><span>| </span><span><span class="constructor">Variant</span> <span class="keyword">of</span> <a href="#type-variant">variant</a></span></code><div class="def-doc"><span class="comment-delim">(*</span><p>accepts clauses keyed by a leading or sole atom</p><span class="comment-delim">*)</span></div></li><li id="type-grammar.Union" class="def variant constructor anchored"><a href="#type-grammar.Union" class="anchor"></a><code><span>| </span><span><span class="constructor">Union</span> <span class="keyword">of</span> <span><a href="#type-grammar">grammar</a> list</span></span></code><div class="def-doc"><span class="comment-delim">(*</span><p>accepts a sexp if any of the listed grammars accepts it</p><span class="comment-delim">*)</span></div></li><li id="type-grammar.Tagged" class="def variant constructor anchored"><a href="#type-grammar.Tagged" class="anchor"></a><code><span>| </span><span><span class="constructor">Tagged</span> <span class="keyword">of</span> <span><a href="#type-grammar">grammar</a> <a href="#type-with_tag">with_tag</a></span></span></code><div class="def-doc"><span class="comment-delim">(*</span><p>annotates a grammar with a client-specific key/value pair</p><span class="comment-delim">*)</span></div></li><li id="type-grammar.Tyvar" class="def variant constructor anchored"><a href="#type-grammar.Tyvar" class="anchor"></a><code><span>| </span><span><span class="constructor">Tyvar</span> <span class="keyword">of</span> string</span></code><div class="def-doc"><span class="comment-delim">(*</span><p>Name of a type variable, e.g. <code>Tyvar "a"</code> for <code>'a</code>. Only meaningful when the body of the innermost enclosing <code>defn</code> defines a corresponding type variable.</p><span class="comment-delim">*)</span></div></li><li id="type-grammar.Tycon" class="def variant constructor anchored"><a href="#type-grammar.Tycon" class="anchor"></a><code><span>| </span><span><span class="constructor">Tycon</span> <span class="keyword">of</span> string * <span><a href="#type-grammar">grammar</a> list</span> * <span><a href="#type-defn">defn</a> list</span></span></code><div class="def-doc"><span class="comment-delim">(*</span><p>Type constructor applied to arguments, and its definition.</p><p>For example, writing <code>Tycon ("tree", [ Integer ], defns)</code> represents <code>int tree</code>, for whatever <code>tree</code> is defined as in <code>defns</code>. The following defines <code>tree</code> as a binary tree with the parameter type stored at the leaves.</p><pre class="language-ocaml"><code>let defns =
|
||
[ { tycon = "tree"
|
||
; tyvars = ["a"]
|
||
; grammar =
|
||
Variant
|
||
{ name_kind = Capitalized
|
||
; clauses =
|
||
[ { name = "Node"
|
||
; args = Cons (Recursive ("node", [Tyvar "a"]), Empty)
|
||
}
|
||
; { name = "Leaf"
|
||
; args = Cons (Recursive ("leaf", [Tyvar "a"]), Empty)
|
||
}
|
||
]
|
||
}
|
||
}
|
||
; { tycon = "node"
|
||
; tyvars = ["a"]
|
||
; grammar = List (Many (Recursive "tree", [Tyvar "a"]))
|
||
}
|
||
; { tycon = "leaf"
|
||
; tyvars = ["a"]
|
||
; grammar = [Tyvar "a"]
|
||
}
|
||
]
|
||
;;</code></pre><p>To illustrate the meaning of <code>Tycon</code> with respect to <code>defns</code>, and to demonstrate one way to access them, it is equivalent to expand the definition of "tree" one level and move the <code>defns</code> to enclosed recursive references:</p><pre class="language-ocaml"><code>Tycon ("tree", [ Integer ], defns)
|
||
-->
|
||
Variant
|
||
{ name_kind = Capitalized
|
||
; clauses =
|
||
[ { name = "Node"
|
||
; args = Cons (Tycon ("node", [Tyvar "a"], defns), Empty)
|
||
}
|
||
; { name = "Leaf"
|
||
; args = Cons (Tycon ("leaf", [Tyvar "a"], defns), Empty)
|
||
}
|
||
]
|
||
}</code></pre><p>This transformation exposes the structure of a grammar with recursive references, while preserving the meaning of recursively-defined elements.</p><span class="comment-delim">*)</span></div></li><li id="type-grammar.Recursive" class="def variant constructor anchored"><a href="#type-grammar.Recursive" class="anchor"></a><code><span>| </span><span><span class="constructor">Recursive</span> <span class="keyword">of</span> string * <span><a href="#type-grammar">grammar</a> list</span></span></code><div class="def-doc"><span class="comment-delim">(*</span><p>Type constructor applied to arguments. Used to denote recursive type references. Only meaningful when used inside the <code>defn</code>s of a <code>Tycon</code> grammar, to refer to a type constructor in the nearest enclosing <code>defn</code> list.</p><span class="comment-delim">*)</span></div></li><li id="type-grammar.Lazy" class="def variant constructor anchored"><a href="#type-grammar.Lazy" class="anchor"></a><code><span>| </span><span><span class="constructor">Lazy</span> <span class="keyword">of</span> <span><a href="#type-grammar">grammar</a> lazy_t</span></span></code><div class="def-doc"><span class="comment-delim">(*</span><p>Lazily computed grammar. Use <code>Lazy</code> to avoid top-level side effects. To define recursive grammars, use <code>Recursive</code> instead.</p><span class="comment-delim">*)</span></div></li></ol></div><div class="spec-doc"><p>Grammar of a sexp.</p></div></div><div class="odoc-spec"><div class="spec type anchored" id="type-list_grammar"><a href="#type-list_grammar" class="anchor"></a><code><span><span class="keyword">and</span> list_grammar</span><span> = </span></code><ol><li id="type-list_grammar.Empty" class="def variant constructor anchored"><a href="#type-list_grammar.Empty" class="anchor"></a><code><span>| </span><span><span class="constructor">Empty</span></span></code><div class="def-doc"><span class="comment-delim">(*</span><p>accepts an empty list of sexps</p><span class="comment-delim">*)</span></div></li><li id="type-list_grammar.Cons" class="def variant constructor anchored"><a href="#type-list_grammar.Cons" class="anchor"></a><code><span>| </span><span><span class="constructor">Cons</span> <span class="keyword">of</span> <a href="#type-grammar">grammar</a> * <a href="#type-list_grammar">list_grammar</a></span></code><div class="def-doc"><span class="comment-delim">(*</span><p>accepts a non-empty list with head and tail matching the given grammars</p><span class="comment-delim">*)</span></div></li><li id="type-list_grammar.Many" class="def variant constructor anchored"><a href="#type-list_grammar.Many" class="anchor"></a><code><span>| </span><span><span class="constructor">Many</span> <span class="keyword">of</span> <a href="#type-grammar">grammar</a></span></code><div class="def-doc"><span class="comment-delim">(*</span><p>accepts zero or more sexps, each matching the given grammar</p><span class="comment-delim">*)</span></div></li><li id="type-list_grammar.Fields" class="def variant constructor anchored"><a href="#type-list_grammar.Fields" class="anchor"></a><code><span>| </span><span><span class="constructor">Fields</span> <span class="keyword">of</span> <a href="#type-record">record</a></span></code><div class="def-doc"><span class="comment-delim">(*</span><p>accepts sexps representing fields of a record</p><span class="comment-delim">*)</span></div></li></ol></div><div class="spec-doc"><p>Grammar of a list of sexps.</p></div></div><div class="odoc-spec"><div class="spec type anchored" id="type-case_sensitivity"><a href="#type-case_sensitivity" class="anchor"></a><code><span><span class="keyword">and</span> case_sensitivity</span><span> = </span></code><ol><li id="type-case_sensitivity.Case_insensitive" class="def variant constructor anchored"><a href="#type-case_sensitivity.Case_insensitive" class="anchor"></a><code><span>| </span><span><span class="constructor">Case_insensitive</span></span></code><div class="def-doc"><span class="comment-delim">(*</span><p>Comparison is case insensitive. Used for custom parsers.</p><span class="comment-delim">*)</span></div></li><li id="type-case_sensitivity.Case_sensitive" class="def variant constructor anchored"><a href="#type-case_sensitivity.Case_sensitive" class="anchor"></a><code><span>| </span><span><span class="constructor">Case_sensitive</span></span></code><div class="def-doc"><span class="comment-delim">(*</span><p>Comparison is case sensitive. Used for polymorphic variants.</p><span class="comment-delim">*)</span></div></li><li id="type-case_sensitivity.Case_sensitive_except_first_character" class="def variant constructor anchored"><a href="#type-case_sensitivity.Case_sensitive_except_first_character" class="anchor"></a><code><span>| </span><span><span class="constructor">Case_sensitive_except_first_character</span></span></code><div class="def-doc"><span class="comment-delim">(*</span><p>Comparison is case insensitive for the first character and case sensitive afterward. Used for regular variants.</p><span class="comment-delim">*)</span></div></li></ol></div><div class="spec-doc"><p>Case sensitivity options for names of variant constructors.</p></div></div><div class="odoc-spec"><div class="spec type anchored" id="type-variant"><a href="#type-variant" class="anchor"></a><code><span><span class="keyword">and</span> variant</span><span> = </span><span>{</span></code><ol><li id="type-variant.case_sensitivity" class="def record field anchored"><a href="#type-variant.case_sensitivity" class="anchor"></a><code><span>case_sensitivity : <a href="#type-case_sensitivity">case_sensitivity</a>;</span></code></li><li id="type-variant.clauses" class="def record field anchored"><a href="#type-variant.clauses" class="anchor"></a><code><span>clauses : <span><span><a href="#type-clause">clause</a> <a href="#type-with_tag_list">with_tag_list</a></span> list</span>;</span></code></li></ol><code><span>}</span></code></div><div class="spec-doc"><p>Grammar of variants. Accepts any sexp matching one of the clauses.</p></div></div><div class="odoc-spec"><div class="spec type anchored" id="type-clause"><a href="#type-clause" class="anchor"></a><code><span><span class="keyword">and</span> clause</span><span> = </span><span>{</span></code><ol><li id="type-clause.name" class="def record field anchored"><a href="#type-clause.name" class="anchor"></a><code><span>name : string;</span></code></li><li id="type-clause.clause_kind" class="def record field anchored"><a href="#type-clause.clause_kind" class="anchor"></a><code><span>clause_kind : <a href="#type-clause_kind">clause_kind</a>;</span></code></li></ol><code><span>}</span></code></div><div class="spec-doc"><p>Grammar of a single variant clause. Accepts sexps based on the <code>clause_kind</code>.</p></div></div><div class="odoc-spec"><div class="spec type anchored" id="type-clause_kind"><a href="#type-clause_kind" class="anchor"></a><code><span><span class="keyword">and</span> clause_kind</span><span> = </span></code><ol><li id="type-clause_kind.Atom_clause" class="def variant constructor anchored"><a href="#type-clause_kind.Atom_clause" class="anchor"></a><code><span>| </span><span><span class="constructor">Atom_clause</span></span></code></li><li id="type-clause_kind.List_clause" class="def variant constructor anchored"><a href="#type-clause_kind.List_clause" class="anchor"></a><code><span>| </span><span><span class="constructor">List_clause</span> <span class="keyword">of</span> </span><span>{</span></code><ol><li id="type-clause_kind.args" class="def record field anchored"><a href="#type-clause_kind.args" class="anchor"></a><code><span>args : <a href="#type-list_grammar">list_grammar</a>;</span></code></li></ol><code><span>}</span></code></li></ol></div><div class="spec-doc"><p>Grammar of a single variant clause's contents. <code>Atom_clause</code> accepts an atom matching the clause's name. <code>List_clause</code> accepts a list whose head is an atom matching the clause's name and whose tail matches <code>args</code>. The clause's name is matched modulo the variant's <code>name_kind</code>.</p></div></div><div class="odoc-spec"><div class="spec type anchored" id="type-record"><a href="#type-record" class="anchor"></a><code><span><span class="keyword">and</span> record</span><span> = </span><span>{</span></code><ol><li id="type-record.allow_extra_fields" class="def record field anchored"><a href="#type-record.allow_extra_fields" class="anchor"></a><code><span>allow_extra_fields : bool;</span></code></li><li id="type-record.fields" class="def record field anchored"><a href="#type-record.fields" class="anchor"></a><code><span>fields : <span><span><a href="#type-field">field</a> <a href="#type-with_tag_list">with_tag_list</a></span> list</span>;</span></code></li></ol><code><span>}</span></code></div><div class="spec-doc"><p>Grammar of a record. Accepts any list of sexps specifying each of the fields, regardless of order. If <code>allow_extra_fields</code> is specified, ignores sexps with names not found in <code>fields</code>.</p></div></div><div class="odoc-spec"><div class="spec type anchored" id="type-field"><a href="#type-field" class="anchor"></a><code><span><span class="keyword">and</span> field</span><span> = </span><span>{</span></code><ol><li id="type-field.name" class="def record field anchored"><a href="#type-field.name" class="anchor"></a><code><span>name : string;</span></code></li><li id="type-field.required" class="def record field anchored"><a href="#type-field.required" class="anchor"></a><code><span>required : bool;</span></code></li><li id="type-field.args" class="def record field anchored"><a href="#type-field.args" class="anchor"></a><code><span>args : <a href="#type-list_grammar">list_grammar</a>;</span></code></li></ol><code><span>}</span></code></div><div class="spec-doc"><p>Grammar of a record field. A field must show up exactly once in a record if <code>required</code>, or at most once otherwise. Accepts a list headed by <code>name</code> as an atom, followed by sexps matching <code>args</code>.</p></div></div><div class="odoc-spec"><div class="spec type anchored" id="type-with_tag"><a href="#type-with_tag" class="anchor"></a><code><span><span class="keyword">and</span> <span>'a with_tag</span></span><span> = </span><span>{</span></code><ol><li id="type-with_tag.key" class="def record field anchored"><a href="#type-with_tag.key" class="anchor"></a><code><span>key : string;</span></code></li><li id="type-with_tag.value" class="def record field anchored"><a href="#type-with_tag.value" class="anchor"></a><code><span>value : <a href="../Sexp/index.html#type-t">Sexp.t</a>;</span></code></li><li id="type-with_tag.grammar" class="def record field anchored"><a href="#type-with_tag.grammar" class="anchor"></a><code><span>grammar : <span class="type-var">'a</span>;</span></code></li></ol><code><span>}</span></code></div><div class="spec-doc"><p>Grammar tagged with client-specific key/value pair.</p></div></div><div class="odoc-spec"><div class="spec type anchored" id="type-with_tag_list"><a href="#type-with_tag_list" class="anchor"></a><code><span><span class="keyword">and</span> <span>'a with_tag_list</span></span><span> = </span></code><ol><li id="type-with_tag_list.Tag" class="def variant constructor anchored"><a href="#type-with_tag_list.Tag" class="anchor"></a><code><span>| </span><span><span class="constructor">Tag</span> <span class="keyword">of</span> <span><span><span class="type-var">'a</span> <a href="#type-with_tag_list">with_tag_list</a></span> <a href="#type-with_tag">with_tag</a></span></span></code></li><li id="type-with_tag_list.No_tag" class="def variant constructor anchored"><a href="#type-with_tag_list.No_tag" class="anchor"></a><code><span>| </span><span><span class="constructor">No_tag</span> <span class="keyword">of</span> <span class="type-var">'a</span></span></code></li></ol></div></div><div class="odoc-spec"><div class="spec type anchored" id="type-defn"><a href="#type-defn" class="anchor"></a><code><span><span class="keyword">and</span> defn</span><span> = </span><span>{</span></code><ol><li id="type-defn.tycon" class="def record field anchored"><a href="#type-defn.tycon" class="anchor"></a><code><span>tycon : string;</span></code></li><li id="type-defn.tyvars" class="def record field anchored"><a href="#type-defn.tyvars" class="anchor"></a><code><span>tyvars : <span>string list</span>;</span></code></li><li id="type-defn.grammar" class="def record field anchored"><a href="#type-defn.grammar" class="anchor"></a><code><span>grammar : <a href="#type-grammar">grammar</a>;</span></code></li></ol><code><span>}</span></code></div><div class="spec-doc"><p>Grammar of a recursive type definition. Names the <code>tycon</code> being defined, and the <code>tyvars</code> it takes as parameters. Specifies the <code>grammar</code> of the <code>tycon</code>. The grammar may refer to any of the <code>tyvars</code>, and to any of the <code>tycon</code>s from the same set of <code>Recursive</code> definitions.</p></div></div><div class="odoc-spec"><div class="spec type anchored" id="type-t"><a href="#type-t" class="anchor"></a><code><span><span class="keyword">type</span> <span>_ t</span></span><span> = </span><span>{</span></code><ol><li id="type-t.untyped" class="def record field anchored"><a href="#type-t.untyped" class="anchor"></a><code><span>untyped : <a href="#type-grammar">grammar</a>;</span></code></li></ol><code><span>}</span></code></div><div class="spec-doc"><p>Top-level grammar type. Has a phantom type parameter to associate each grammar with the type its sexps represent. This makes it harder to apply grammars to the wrong type, while grammars can still be easily coerced to a new type if needed.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-coerce"><a href="#val-coerce" class="anchor"></a><code><span><span class="keyword">val</span> coerce : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <a href="#type-t">t</a></span></span></code></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-tag"><a href="#val-tag" class="anchor"></a><code><span><span class="keyword">val</span> tag : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span>key:string <span class="arrow">-></span></span> <span>value:<a href="../Sexp/index.html#type-t">Sexp.t</a> <span class="arrow">-></span></span> <span><span class="type-var">'a0</span> <a href="#type-t">t</a></span></span></code></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-doc_comment_tag"><a href="#val-doc_comment_tag" class="anchor"></a><code><span><span class="keyword">val</span> doc_comment_tag : string</span></code></div><div class="spec-doc"><p>This reserved key is used for all tags generated from doc comments.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-type_name_tag"><a href="#val-type_name_tag" class="anchor"></a><code><span><span class="keyword">val</span> type_name_tag : string</span></code></div><div class="spec-doc"><p>This reserved key can be used to associate a type name with a grammar.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-assoc_tag"><a href="#val-assoc_tag" class="anchor"></a><code><span><span class="keyword">val</span> assoc_tag : string</span></code></div><div class="spec-doc"><p>This reserved key indicates that a sexp represents a key/value association. The tag's value is ignored.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-assoc_key_tag"><a href="#val-assoc_key_tag" class="anchor"></a><code><span><span class="keyword">val</span> assoc_key_tag : string</span></code></div><div class="spec-doc"><p>This reserved key indicates that a sexp is a key in a key/value association. The tag's value is ignored.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-assoc_value_tag"><a href="#val-assoc_value_tag" class="anchor"></a><code><span><span class="keyword">val</span> assoc_value_tag : string</span></code></div><div class="spec-doc"><p>This reserved key indicates that a sexp is a value in a key/value association. The tag's value is ignored.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-completion_suggested"><a href="#val-completion_suggested" class="anchor"></a><code><span><span class="keyword">val</span> completion_suggested : string</span></code></div><div class="spec-doc"><p>When the key is set to <code>Atom "false"</code> for a variant clause, that clause should not be suggested in auto-completion based on the sexp grammar.</p></div></div></div></body></html> |