# pon # pan object notation # # v 0.1 ; 2024-09-09 ## tokens paren_open =| "(" ; paren_close =| ")" ; bracket_open =| "[" ; bracket_close =| "]" ; dot =| "." ; quote =| "\"" ; backslash =| "\\" ; whitespace =| " " | "\t" | "\v" # XXX | "\r" | "\n" | "\f" # XXX ; any =| . ; semicolon =| ";" ; newline =| "\n" ; # XXX ... comments may change ## grammar start =| _ pon ; pon =| paren_open _ identifier body paren_close _ # record | bracket_open _ pon* bracket_close _ # list ; body =| ( dot identifier pon )* # field, null | identifier # literal | string # string ; identifier =| ( !paren_open !paren_close !bracket_open !bracket_close !dot !quote !backslash !whitespace any )+ _ ; string =| quote string_content* quote _ ; string_content =| !quote !backslash any # "hello" | backslash quote # " \" " | backslash backslash # " \\ " ; _ =| whitespace | semicolon comment* newline # maybe '/' instead ? ; comment =| !newline any ; # v 0.2 ; 2024-09-10 # ( null ) # ( u8 1 ) # ( rec field (x) ) # ( list (x) ) # # XXX ( _ ) # ( _ _ ) # ( _ _ (_) ) # ( _ (_) ) # # XXX worth considering that records & lists cannot be empty in this variation... # # records extend primitives # XXX lists overlap strings ## tokens PAREN_OPEN =| "(" ; PAREN_CLOSE =| ")" ; QUOTE =| "\"" ; BACKSLASH =| "\\" ; SPACE =| " " ; TAB =| "\t" ; RETURN =| "\r" ; NEWLINE =| "\n" ; SEMICOLON =| ";" ; ANY =| . ; ## grammar start =| _ pon ; _ = | SPACE | TAB | RETURN | NEWLINE | comment ; comment =| SEMICOLON ( !NEWLINE ANY )* NEWLINE ; pon =| PAREN_OPEN _ type value PAREN_CLOSE _ ; type =| string ; string = | literal | quoted ; literal =| ( !PAREN_OPEN !PAREN_CLOSE !SPACE !TAB !RETURN !NEWLINE !SEMICOLON ANY )+ _ ; quoted =| QUOTE char* QUOTE _ ; char = | !QUOTE !BACKSLASH ANY | BACKSLASH QUOTE | BACKSLASH BACKSLASH ; value = | string | record | list ; record =| ( string pon )+ ; list =| pon* ;