diff options
Diffstat (limited to 'spec/parser.ebnf')
| -rw-r--r-- | spec/parser.ebnf | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/spec/parser.ebnf b/spec/parser.ebnf new file mode 100644 index 0000000..ce7fa83 --- /dev/null +++ b/spec/parser.ebnf @@ -0,0 +1,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 ( '%' | '=' blank* datum ) + | clad_datum + ; + +list : datum_unit+ list_tail? blank* ; + +list_tail : '.' blank+ datum_unit + +quote_expr : ( "'" | "`" | "," ) blank* 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' ; |
