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_string | clad_datum ; bare_string : ( '.' | '+' | '-' | DIGIT ) ( bare_str_elt | '.' )* | bare_str_elt+ ; clad_datum : '\' bare_esc_str | '|' pipe_str_elt* '|' | '"' quot_str_elt* '"' | '#' hash_expr | '(' list ')' | '[' list ']' | '{' list '}' | quote_expr ; bare_str_elt : bare_char | '\' bare_esc ; bare_esc_str : bare_esc bare_str_elt* ; pipe_str_elt : ~( '|' | '\' ) | '\' pipe_esc ; quot_str_elt : ~( '"' | '\' ) | '\' quot_esc ; hash_expr : rune clad_datum? | '%' label ( '%' | '=' datum ) | clad_datum ; list : unit* ( '.' unit )? blank* ; quote_expr : ( "'" | "`" | "," ) datum ; bare_char : ALPHA | DIGIT | bare_punct ; bare_punct : '!' | '$' | '%' | '&' | '*' | '+' | '-' | '/' | '<' | '=' | '>' | '?' | '@' | '^' | '_' | '~' ; bare_esc : 33...126 ; pipe_esc : string_esc | '|' ; quot_esc : string_esc | '"' ; string_esc : '\' | 'a' | 'b' | 'e' | 'f' | 'n' | 'r' | 't' | 'v' | 'x' HEXDIG{2} | 'u' '{' HEXDIG+ '}' ; rune : ALPHA ( ALPHA | DIGIT ){0,5} ; label : HEXDIG{1,12} ;