summaryrefslogtreecommitdiff
path: root/spec/parser.ebnf
blob: 9e02fbae537baccfe50177f76d1ff2b4dc33d3da (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
unit          : blank* ( datum blank? | EOF ) ;


blank         : 9...13 | comment ;

datum         : one_datum ( join_char? one_datum )* ;

join_char     : '.' | ':' | '|' ;


comment       : ';' ( skip_unit | skip_line ) ;

skip_unit     : '~' unit ;

skip_line     : ( ~LF )* LF? ;


one_datum     : ( bare_str | clad_datum ) ;

bare_str      : bare_str_elt+ ;

clad_datum    : '\' bare_esc_str
              | '"' quoted_str '"'
              | '#' hash_expr
              | '(' blank* list? ')'
              | '[' blank* list? ']'
              | '{' blank* list? '}'
              | quote_expr
              ;


bare_str_elt  : bare_char | '\' bare_esc ;


bare_esc_str  : bare_esc bare_str_elt* ;

quoted_str    : ( quoted_char | '\' quoted_esc )* ;

hash_expr     : rune clad_datum?
              | '%' label ( '%' | '=' unit )
              | clad_datum
              ;

list          : unit+ ( '.' blank+ unit )? blank* ;

quote_expr    : ( "'" | "`" | "," ) datum ;


bare_char     : letter | digit
              | '!' | '$' | '%' | '&' | '*' | '+' | '-' | '/'
              | '<' | '=' | '>' | '?' | '@' | '^' | '_' | '~'
              ;

bare_esc      : 33...126 ;


quoted_char   : ~( '"' | '\' ) ;

quoted_esc    : '\' | '"' | 'a' | 'b' | 'e'
              | 'f' | 'n' | 'r' | 't' | 'v'
              | 'x' hex_digit{2}
              | 'u' '{' hex_digit+ '}'
              ;


rune          : letter ( letter | digit ){0,5} ;

label         : hex_digit{1,12} ;


letter        : 'a'...'z' | 'A'...'Z' ;

digit         : '0'...'9' ;

hex_digit     : '0'...'9' | 'a'...'f' | 'A'...'F' ;