summaryrefslogtreecommitdiff
path: root/spec/parser.ebnf
blob: 60f7890cd8c114f80ef3a02e360c209cbf2d5e57 (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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
unit          : empty_unit | datum_unit ;


empty_unit    : blank* EOF ;

datum_unit    : blank* datum blank? ;


blank         : 9...13 | comment ;

datum         : join_data | dot_string ;


comment       : ';' ( skip_unit | skip_line ) ;

skip_unit     : '~' unit ;

skip_line     : ( ~10 )* 10? ;


join_data     : one_datum ( join_char? one_datum )*

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

dot_string    : '.'{2,}


one_datum     : ( num_string | bare_string | clad_datum ) ;

num_string    : ( '+' | '-' )? digit ( bare_str_elt | '.' )* ;

bare_string   : 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 ( '%' | '=' datum_unit )
              | clad_datum
              ;

list          : datum_unit+ list_tail? blank* ;

list_tail     : '.' blank+ datum_unit

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' ;