JXC Syntax¶
Input Encoding¶
All JXC source is expected to be valid UTF-8.
Syntax Rules¶
Note that the Syntax Diagrams are generated directly from this document.
All JXC source is expected to be valid UTF-8.
Note that the Syntax Diagrams are generated directly from this document.
{
value: Sequence[
Whitespace<Optional>()
Choice[
Sequence[
Sequence<Optional>[
MatchGroupRef "annotation"
# For non-container values, whitespace is required after the annotation
Whitespace()
]
Choice[
MatchGroupRef "string"
MatchGroupRef "string_raw"
MatchGroupRef "string_base64"
MatchGroupRef "string_datetime"
MatchGroupRef "number"
MatchGroupRef "float_literal"
String "true"
String "false"
String "null"
]
]
Sequence[
Sequence<Optional>[
MatchGroupRef "annotation"
# For container values, whitespace is optional after the annotation
Whitespace<Optional>()
]
Choice[
MatchGroupRef "object"
MatchGroupRef "array"
MatchGroupRef "expression"
]
]
]
Whitespace<Optional>()
]
annotation: Sequence[
Sequence<Optional>[
Character '!'
Whitespace<Optional>()
]
MatchGroupRef "dotted_identifier"
Sequence<Optional>[
Character '<'
Choice[
Whitespace<Optional>()
MatchGroupRef<OneOrMore> "annotation_inner"
]
Character '>'
]
]
annotation_inner: Sequence[
Whitespace<Optional>()
Choice[
MatchGroupRef "dotted_identifier"
MatchGroupRef "string"
MatchGroupRef "string_raw"
MatchGroupRef "string_datetime"
MatchGroupRef "number"
MatchGroupRef "float_literal"
String "true"
String "false"
String "null"
Character '!'
Character '*'
Character '?'
Character '|'
Character '&'
Character '='
Character ','
Sequence[
Character '<'
MatchGroupRef<ZeroOrMore> "annotation_inner"
Character '>'
]
Sequence[
Character '('
MatchGroupRef<ZeroOrMore> "annotation_inner"
Character ')'
]
]
Whitespace<Optional>()
]
object: Sequence[
Character '{'
Choice[
Whitespace<Optional>()
Sequence[
Sequence<OneOrMore>[repeat[Choice[Character ',', MatchGroupRef "line_break"]], [
Whitespace<Optional>()
Choice[
MatchGroupRef<OneOrMore>[repeat('.'), "identifier_object_key"]
MatchGroupRef 'string'
MatchGroupRef 'number_object_key'
String "null"
String "true"
String "false"
]
Whitespace<Optional>()
Character ':'
MatchGroupRef "value"
]]
Choice<Optional>[
Group{
name: 'trailing separator'
value: Sequence[
Choice[
Character ','
MatchGroupRef "line_break"
]
Whitespace<Optional>()
]
}
]
]
]
Character '}'
]
array: Sequence[
Character '['
Choice[
Whitespace<Optional>()
Sequence[
Sequence<OneOrMore>[repeat[Choice[Character ',', MatchGroupRef "line_break"]], [
MatchGroupRef "value"
]]
Choice<Optional>[
Group{
name: 'trailing separator'
value: Sequence[
Choice[
Character ','
MatchGroupRef "line_break"
]
Whitespace<Optional>()
]
}
]
]
]
Character ']'
]
expression: Sequence[
Character '('
Choice[
Whitespace<Optional>()
MatchGroupRef<OneOrMore> "expression_item"
]
Character ')'
]
expression_item: Sequence[
Whitespace<Optional>()
Choice[
MatchGroupRef "identifier"
MatchGroupRef "string"
MatchGroupRef "string_raw"
MatchGroupRef "string_base64"
MatchGroupRef "string_datetime"
MatchGroupRef "number_unsigned"
String "true"
String "false"
String "null"
String "nan"
String "inf"
MatchGroupRef "expression_operator"
MatchGroupRef "line_break"
Character ','
Character ':'
Character '@'
Sequence[
Character '['
Choice[
MatchGroupRef<OneOrMore> "expression_item"
Whitespace<Optional>()
]
Character ']'
]
Sequence[
Character '{'
Choice[
MatchGroupRef<OneOrMore> "expression_item"
Whitespace<Optional>()
]
Character '}'
]
Sequence[
Character '('
Choice[
MatchGroupRef<OneOrMore> "expression_item"
Whitespace<Optional>()
]
Character ')'
]
]
Whitespace<Optional>()
]
expression_operator: Choice[
Character '|'
Character '&'
Character '!'
Character '='
Character '+'
Character '-'
Character '*'
Character '/'
Character '\\'
Character '%'
Character '^'
Character '.'
Character '?'
Character '~'
Character '<'
Character '>'
Character '`'
Character ';'
]
dotted_identifier: Sequence[
MatchGroupRef<OneOrMore>[
repeat[Sequence[
Whitespace<Optional>()
Character '.'
Whitespace<Optional>()
]]
"identifier"
]
]
identifier: Sequence[
Choice[
CharacterRange['a', 'z']
CharacterRange['A', 'Z']
Character '_'
Character '$'
]
Choice<ZeroOrMore>[
CharacterRange['a', 'z']
CharacterRange['A', 'Z']
CharacterRange['0', '9']
Character '_'
Character '$'
]
]
identifier_object_key: Sequence[
Choice[
CharacterRange['a', 'z']
CharacterRange['A', 'Z']
Character '_'
Character '$'
Character '*'
]
Choice<ZeroOrMore>[
CharacterRange['a', 'z']
CharacterRange['A', 'Z']
CharacterRange['0', '9']
Character '_'
Character '$'
Character '*'
]
]
string: Sequence[
Choice[
Sequence[
Character '"'
Choice<ZeroOrMore>[
CharacterRange{ exclusions: ['\\', '"'] }
MatchGroupRef "string_escape_sequence"
]
Character '"'
]
Sequence[
Character "'"
Choice<ZeroOrMore>[
CharacterRange{ exclusions: ['\\', "'"] }
MatchGroupRef "string_escape_sequence"
]
Character "'"
]
]
]
string_escape_sequence: Sequence[
Character '\\'
Choice[
Sequence[ Character '"', Comment 'double quote' ]
Sequence[ Character "'", Comment 'single quote' ]
Sequence[ Character '\\', Comment 'backslash' ]
Sequence[ Character '/', Comment 'forward slash' ]
Sequence[ Character 'b', Comment 'backspace' ]
Sequence[ Character 'f', Comment 'formfeed' ]
Sequence[ Character 'n', Comment 'line break' ]
Sequence[ Character 'r', Comment 'carriage return' ]
Sequence[ Character 't', Comment 'horizontal tab' ]
Sequence[
Character 'x'
MatchGroupRef<OneOrMore>[ repeat(2x), 'hex_digit' ]
Comment 'one-byte character'
]
Sequence[
Character 'u'
MatchGroupRef<OneOrMore>[ repeat(4x), 'hex_digit' ]
Comment 'utf16-be codepoint'
]
Sequence[
Character 'U'
MatchGroupRef<OneOrMore>[ repeat(8x), 'hex_digit' ]
Comment 'utf32-be codepoint'
]
]
]
string_raw: Sequence[
Character 'r'
Choice[
Sequence[
Character '"'
MatchGroupRef<Optional> "heredoc"
Character '('
Choice<ZeroOrMore>[
CharacterRange()
]
Character ')'
MatchGroupRef<Optional> "heredoc"
Character '"'
]
Sequence[
Character "'"
MatchGroupRef<Optional> "heredoc"
Character '('
Choice<ZeroOrMore>[
CharacterRange()
]
Character ')'
MatchGroupRef<Optional> "heredoc"
Character '\''
]
]
]
heredoc: Sequence[
Choice[
CharacterRange[ 'a', 'z' ]
CharacterRange[ 'A', 'Z' ]
Character '_'
]
Choice<ZeroOrMore>[repeat(1x, 14x), [
CharacterRange[ 'a', 'z' ]
CharacterRange[ 'A', 'Z' ]
CharacterRange[ '0', '9' ]
Character '_'
]]
Comment '(max 15 characters)'
]
string_base64: Sequence[
Choice[
Sequence[
String 'b64"'
Sequence<ZeroOrMore>[
MatchGroupRef "base64_digit"
]
Character '"'
]
Sequence[
String "b64'"
Sequence<ZeroOrMore>[
MatchGroupRef "base64_digit"
]
Character "'"
]
Sequence[
String 'b64"('
Whitespace<Optional>()
Sequence<ZeroOrMore>[
MatchGroupRef "base64_digit"
Whitespace<Optional>()
]
String ')"'
]
Sequence[
String "b64'("
Whitespace<Optional>()
Sequence<ZeroOrMore>[
MatchGroupRef "base64_digit"
Whitespace<Optional>()
]
String ")'"
]
]
Comment "Digit count must be a multiple of 4"
]
string_datetime: Choice[
Sequence[
String 'dt"'
MatchGroupRef "datetime_iso8601"
Character '"'
]
Sequence[
String 'dt\''
MatchGroupRef "datetime_iso8601"
Character '\''
]
]
datetime_iso8601: Sequence[
MatchGroupRef "date"
Sequence<Optional>[
Character 'T'
MatchGroupRef "time"
MatchGroupRef<Optional> "timezone"
]
]
date: Sequence[
Group{
name: 'Year'
value: Sequence[
Choice<Optional>[
Character '+'
Character '-'
]
Sequence<OneOrMore>[repeat(4x, 5x), [ CharacterRange[ '0', '9' ] ]]
]
}
Character '-'
Group{
name: 'Month'
value: Sequence[
CharacterRange[ '0', '9' ]
CharacterRange[ '0', '9' ]
]
}
Character '-'
Group{
name: 'Day'
value: Sequence[
CharacterRange[ '0', '9' ]
CharacterRange[ '0', '9' ]
]
}
]
time: Sequence[
CharacterRange[ '0', '9' ]
CharacterRange[ '0', '9' ]
Character ':'
CharacterRange[ '0', '9' ]
CharacterRange[ '0', '9' ]
Sequence<Optional>[
Character ':'
CharacterRange[ '0', '9' ]
CharacterRange[ '0', '9' ]
]
Sequence<Optional>[
Character '.'
Sequence<OneOrMore>[repeat(1x, 12x), [ CharacterRange[ '0', '9' ] ]]
]
]
timezone: Choice[
Character 'Z'
Sequence[
Choice[
Character '+'
Character '-'
]
CharacterRange[ '0', '9' ]
CharacterRange[ '0', '9' ]
Character ':'
CharacterRange[ '0', '9' ]
CharacterRange[ '0', '9' ]
]
]
number: Sequence[
Choice<Optional>[
Character '+'
Character '-'
]
MatchGroupRef "number_unsigned"
]
number_object_key: Sequence[
Choice<Optional>[
Character '+'
Character '-'
]
Choice[
MatchGroupRef "number_unsigned_hex"
MatchGroupRef "number_unsigned_bin"
MatchGroupRef "number_unsigned_oct"
Sequence[
MatchGroupRef "number_unsigned_dec"
MatchGroupRef<Optional> "exponent_positive"
]
]
]
number_unsigned: Sequence[
Choice[
MatchGroupRef "number_unsigned_hex"
MatchGroupRef "number_unsigned_bin"
MatchGroupRef "number_unsigned_oct"
Sequence[
MatchGroupRef "number_unsigned_dec"
Choice<Optional>[
MatchGroupRef "exponent_positive"
MatchGroupRef "exponent_negative"
]
]
Sequence[
MatchGroupRef "number_unsigned_dec"
Character '.'
CharacterRange<OneOrMore>['0', '9']
Choice<Optional>[
MatchGroupRef "exponent_positive"
MatchGroupRef "exponent_negative"
]
]
]
]
number_unsigned_dec: Sequence[
CharacterRange['1', '9']
Choice<ZeroOrMore>[
CharacterRange['0', '9']
]
]
number_unsigned_hex: Sequence[
Choice[
String "0x"
String "0X"
]
MatchGroupRef<OneOrMore> "hex_digit"
]
number_unsigned_bin: Sequence[
Choice[
String "0b"
String "0B"
]
Choice<OneOrMore>[
Character '0'
Character '1'
]
]
number_unsigned_oct: Sequence[
Choice[
String "0o"
String "0O"
]
CharacterRange<OneOrMore>['0', '7']
]
number_suffix: Sequence[
Choice[
CharacterRange['a', 'z']
CharacterRange['A', 'Z']
Character '%'
]
Choice<ZeroOrMore>[
CharacterRange['a', 'z']
CharacterRange['A', 'Z']
CharacterRange['0', '9']
Character '%'
]
Comment "15 chars max"
]
exponent_positive: Sequence[
Choice[
Character 'e'
Character 'E'
]
Character<Optional> '+'
]
exponent_negative: Sequence[
Choice[
Character 'e'
Character 'E'
]
Character '-'
]
hex_digit: Choice[
CharacterRange['a', 'f']
CharacterRange['A', 'F']
CharacterRange['0', '9']
]
base64_digit: Choice[
CharacterRange['a', 'z']
CharacterRange['A', 'Z']
CharacterRange['0', '9']
Character '+'
Character '/'
Character '='
]
float_literal: Choice[
String "nan"
Sequence[
Choice<Optional>[
Character '+'
Character '-'
]
String "inf"
]
]
whitespace_optional: Choice<ZeroOrMore>[
Character ' '
Character '\t'
Character '\n'
Character '\r'
]
whitespace: Choice<OneOrMore>[
Character ' '
Character '\t'
Character '\n'
Character '\r'
]
line_break: Choice<OneOrMore>[
Character '\n'
Character '\r'
]
}