document ::= (header NEWLINE)? (comment | record | empty-line) (NEWLINE (comment | record | empty-line))* NEWLINE? | header header ::= OPENBRACK NOTCRLF* comment ::= SEMICOLON NOTCRLF* empty-line ::= WHITESPACE* record ::= field (PIPE field)* field ::= WHITESPACE* field-data WHITESPACE* field-data ::= escaped | unescaped escaped ::= DQUOTE (TEXTDATA | WHITESPACE | NEWLINE | PIPE | DQUOTE DQUOTE)* DQUOTE unescaped ::= (TEXTDATA (WHITESPACE* (TEXTDATA | DQUOTE))*)? HTAB ::= #x09 LF ::= #x0A VTAB ::= #x0B FF ::= #x0C CR ::= #x0D SPACE ::= #x20 DQUOTE ::= #x22 SEMICOLON ::= #x3B OPENBRACK ::= #x5B PIPE ::= #x7C WHITESPACE ::= SPACE | FF | HTAB | VTAB NOTCRLF ::= [#x00-#x09#x0B-#x0C#x0E-#x10FFFF] TEXTDATA ::= [#x00-#x08#x0E-#x1F#x21#x23-#x5A#x5C-#x7B#x7D-#x10FFFF] NEWLINE ::= CR LF?