SYNTAX.md for Lisp
This commit is contained in:
parent
c3edf193c4
commit
a824e2d9e8
1 changed files with 224 additions and 0 deletions
224
src/languages/lisp/SYNTAX.md
Normal file
224
src/languages/lisp/SYNTAX.md
Normal file
|
|
@ -0,0 +1,224 @@
|
|||
# Lisp Syntax
|
||||
|
||||
This is a small Lisp-like concrete syntax used for parser and source span experiments.
|
||||
|
||||
## Grammar
|
||||
|
||||
This grammar is intentionally semi-formal. `Whitespace` may appear between the major syntactic parts shown below.
|
||||
|
||||
```txt
|
||||
Program ::= Expr*
|
||||
|
||||
Expr ::= Identifier
|
||||
| Number
|
||||
| RoundList
|
||||
| SquareList
|
||||
|
||||
RoundList ::= "(" Expr* ")"
|
||||
|
||||
SquareList ::= "[" SquareBody? "]"
|
||||
SquareBody ::= LeadingComma? SquareItems? TrailingComma?
|
||||
LeadingComma ::= ","
|
||||
TrailingComma ::= ","
|
||||
SquareItems ::= Expr ("," Expr)*
|
||||
|
||||
Number ::= Digit+
|
||||
|
||||
Identifier ::= IdentifierStart IdentifierPart*
|
||||
|
||||
IdentifierStart
|
||||
::= AsciiLetter
|
||||
| "_"
|
||||
| "-"
|
||||
|
||||
IdentifierPart
|
||||
::= IdentifierStart
|
||||
| Digit
|
||||
|
||||
Digit ::= "0" | "1" | "2" | "3" | "4"
|
||||
| "5" | "6" | "7" | "8" | "9"
|
||||
|
||||
AsciiLetter ::= "a" ... "z" | "A" ... "Z"
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- `Program` may be empty.
|
||||
- `RoundList` elements are whitespace-separated only; commas have no special meaning there.
|
||||
- `SquareList` elements require commas between neighboring expressions.
|
||||
- `SquareList` permits at most one leading comma and at most one trailing comma.
|
||||
- `foo(bar)` is allowed because it is parsed as two adjacent expressions: `foo` and `(bar)`.
|
||||
|
||||
## Program
|
||||
|
||||
A program is a sequence of zero or more expressions.
|
||||
|
||||
```lisp
|
||||
foo
|
||||
foo 123
|
||||
foo(bar)
|
||||
(foo 1 2) [bar, 3, baz]
|
||||
```
|
||||
|
||||
Empty input is valid.
|
||||
|
||||
Whitespace may appear between expressions, but it is not required when the next expression starts with a delimiter:
|
||||
|
||||
```lisp
|
||||
foo(bar)
|
||||
```
|
||||
|
||||
is treated like:
|
||||
|
||||
```lisp
|
||||
foo (bar)
|
||||
```
|
||||
|
||||
## Expressions
|
||||
|
||||
An expression is one of:
|
||||
|
||||
- identifier
|
||||
- number
|
||||
- round list
|
||||
- square list
|
||||
|
||||
## Identifiers
|
||||
|
||||
Identifiers must start with:
|
||||
|
||||
- ASCII letter
|
||||
- `_`
|
||||
- `-`
|
||||
|
||||
After the first code point, identifiers may contain:
|
||||
|
||||
- ASCII letters
|
||||
- digits
|
||||
- `_`
|
||||
- `-`
|
||||
|
||||
Examples:
|
||||
|
||||
```lisp
|
||||
foo
|
||||
abc123
|
||||
abc_123
|
||||
name-with-dash
|
||||
_private
|
||||
-operator-like
|
||||
```
|
||||
|
||||
Not identifiers:
|
||||
|
||||
```lisp
|
||||
123abc
|
||||
@foo
|
||||
💥
|
||||
```
|
||||
|
||||
## Numbers
|
||||
|
||||
Numbers are non-empty sequences of ASCII digits.
|
||||
|
||||
Examples:
|
||||
|
||||
```lisp
|
||||
0
|
||||
1
|
||||
123
|
||||
00123
|
||||
```
|
||||
|
||||
No signs, decimals, exponents, separators, or non-ASCII digits are supported.
|
||||
|
||||
These are not valid numbers:
|
||||
|
||||
```lisp
|
||||
-1
|
||||
1.2
|
||||
1e5
|
||||
123abc
|
||||
```
|
||||
|
||||
## Round Lists
|
||||
|
||||
Round lists use parentheses and contain zero or more expressions.
|
||||
|
||||
```lisp
|
||||
()
|
||||
(foo)
|
||||
(foo 1 2)
|
||||
(foo (bar 1) baz)
|
||||
```
|
||||
|
||||
Round lists do not use separators. Commas are not special in round lists.
|
||||
|
||||
## Square Lists
|
||||
|
||||
Square lists use brackets and require commas between neighboring elements.
|
||||
|
||||
```lisp
|
||||
[]
|
||||
[foo]
|
||||
[foo, bar]
|
||||
[foo, 1, (bar 2)]
|
||||
```
|
||||
|
||||
Square lists allow one optional leading comma:
|
||||
|
||||
```lisp
|
||||
[,foo]
|
||||
[,foo, bar]
|
||||
```
|
||||
|
||||
Square lists allow one optional trailing comma:
|
||||
|
||||
```lisp
|
||||
[foo,]
|
||||
[foo, bar,]
|
||||
```
|
||||
|
||||
Leading and trailing commas can be combined:
|
||||
|
||||
```lisp
|
||||
[,foo, bar,]
|
||||
```
|
||||
|
||||
Repeated leading commas are invalid:
|
||||
|
||||
```lisp
|
||||
[, , foo]
|
||||
```
|
||||
|
||||
Missing separators between neighboring elements are invalid:
|
||||
|
||||
```lisp
|
||||
[foo bar]
|
||||
[foo, bar baz]
|
||||
```
|
||||
|
||||
Repeated separators after an element are invalid:
|
||||
|
||||
```lisp
|
||||
[foo,, bar]
|
||||
[foo, bar,,]
|
||||
```
|
||||
|
||||
## Delimiters
|
||||
|
||||
Lists must be closed with the matching delimiter:
|
||||
|
||||
```lisp
|
||||
(foo)
|
||||
[foo]
|
||||
```
|
||||
|
||||
These are invalid:
|
||||
|
||||
```lisp
|
||||
(foo]
|
||||
[foo)
|
||||
(foo
|
||||
[foo
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue