jcr = *( sp-cmt / directive / root-rule / rule ) sp-cmt = spaces / comment spaces = 1*( WSP / CR / LF ) DSPs = ; Directive spaces 1*WSP / ; When in one-line directive 1*sp-cmt ; When in muti-line directive comment = ";" *comment-char comment-end-char comment-char = HTAB / %x20-10FFFF ; Any char other than CR / LF comment-end-char = CR / LF directive = "#" (one-line-directive / multi-line-directive) one-line-directive = [ DSPs ] (directive-def / one-line-tbd-directive-d) *WSP eol multi-line-directive = "{" *sp-cmt ( directive-def / multi-line-tbd-directive-d ) *sp-cmt "}" directive-def = jcr-version-d / ruleset-id-d / import-d jcr-version-d = jcr-version-kw DSPs major-version "." minor-version *( DSPs "+" [ DSPs ] extension-id ) major-version = non-neg-integer minor-version = non-neg-integer extension-id = id id = ALPHA *id-tail id-tail = %x21-7C / %x7E-10FFFF ; not spaces, not } ruleset-id-d = ruleset-id-kw DSPs ruleset-id import-d = import-kw DSPs ruleset-id [ DSPs as-kw DSPs ruleset-id-alias ] ruleset-id = id ruleset-id-alias = name one-line-tbd-directive-d = directive-name [ WSP one-line-directive-parameters ] directive-name = name one-line-directive-parameters = *not-eol not-eol = HTAB / %x20-10FFFF eol = CR / LF multi-line-tbd-directive-d = directive-name [ 1*sp-cmt multi-line-directive-parameters ] multi-line-directive-parameters = multi-line-parameters multi-line-parameters = *(comment / q-string / not-multi-line-special) not-multi-line-special = spaces / %x21 / %x23-3A / %x3C-7C / %x7E-10FFFF ; not ", ; or } root-rule = value-rule / group-rule rule = annotations "$" rule-name *sp-cmt "=" *sp-cmt rule-def rule-name = name target-rule-name = annotations "$" [ ruleset-id-alias "." ] rule-name name = ALPHA *( ALPHA / DIGIT / "-" / "_" ) rule-def = member-rule / type-designator rule-def-type-rule / value-rule / group-rule / target-rule-name type-designator = type-kw 1*sp-cmt / ":" *sp-cmt rule-def-type-rule = value-rule / type-choice value-rule = primitive-rule / array-rule / object-rule member-rule = annotations member-name-spec *sp-cmt ":" *sp-cmt type-rule member-name-spec = regex / q-string type-rule = value-rule / type-choice / target-rule-name type-choice = annotations "(" type-choice-items *( choice-combiner type-choice-items ) ")" type-choice-items = *sp-cmt ( type-choice / type-rule ) *sp-cmt annotations = *( "@{" *sp-cmt annotation-set *sp-cmt "}" *sp-cmt ) annotation-set = not-annotation / unordered-annotation / root-annotation / tbd-annotation not-annotation = not-kw unordered-annotation = unordered-kw root-annotation = root-kw tbd-annotation = annotation-name [ spaces annotation-parameters ] annotation-name = name annotation-parameters = multi-line-parameters primitive-rule = annotations primitive-def primitive-def = string-type / string-range / string-value / null-type / boolean-type / true-value / false-value / double-type / float-type / float-range / float-value / integer-type / integer-range / integer-value / sized-int-type / sized-uint-type / ipv4-type / ipv6-type / ipaddr-type / fqdn-type / idn-type / uri-type / phone-type / email-type / datetime-type / date-type / time-type / hex-type / base32hex-type / base32-type / base64url-type / base64-type / any null-type = null-kw boolean-type = boolean-kw true-value = true-kw false-value = false-kw string-type = string-kw string-value = q-string string-range = regex double-type = double-kw float-type = float-kw float-range = float-min ".." [ float-max ] / ".." float-max float-min = float float-max = float float-value = float integer-type = integer-kw integer-range = integer-min ".." [ integer-max ] / ".." integer-max integer-min = integer integer-max = integer integer-value = integer sized-int-type = int-kw pos-integer sized-uint-type = uint-kw pos-integer ipv4-type = ipv4-kw ipv6-type = ipv6-kw ipaddr-type = ipaddr-kw fqdn-type = fqdn-kw idn-type = idn-kw uri-type = uri-kw [ ".." uri-scheme ] phone-type = phone-kw email-type = email-kw datetime-type = datetime-kw date-type = date-kw time-type = time-kw hex-type = hex-kw base32hex-type = base32hex-kw base32-type = base32-kw base64url-type = base64url-kw base64-type = base64-kw any = any-kw object-rule = annotations "{" *sp-cmt [ object-items *sp-cmt ] "}" object-items = object-item [ 1*( sequence-combiner object-item ) / 1*( choice-combiner object-item ) ] object-item = object-item-types *sp-cmt [ repetition *sp-cmt ] object-item-types = object-group / member-rule / target-rule-name object-group = annotations "(" *sp-cmt [ object-items *sp-cmt ] ")" array-rule = annotations "[" *sp-cmt [ array-items *sp-cmt ] "]" array-items = array-item [ 1*( sequence-combiner array-item ) / 1*( choice-combiner array-item ) ] array-item = array-item-types *sp-cmt [ repetition *sp-cmt ] array-item-types = array-group / type-rule array-group = annotations "(" *sp-cmt [ array-items *sp-cmt ] ")" group-rule = annotations "(" *sp-cmt [ group-items *sp-cmt ] ")" group-items = group-item [ 1*( sequence-combiner group-item ) / 1*( choice-combiner group-item ) ] group-item = group-item-types *sp-cmt [ repetition *sp-cmt ] group-item-types = group-group / member-rule / type-rule group-group = group-rule sequence-combiner = "," *sp-cmt choice-combiner = "|" *sp-cmt repetition = optional / one-or-more / repetition-range / zero-or-more optional = "?" one-or-more = "+" [ repetition-step ] zero-or-more = "*" [ repetition-step ] repetition-range = "*" *sp-cmt ( min-max-repetition / min-repetition / max-repetition / specific-repetition ) min-max-repetition = min-repeat ".." max-repeat [ repetition-step ] min-repetition = min-repeat ".." [ repetition-step ] max-repetition = ".." max-repeat [ repetition-step ] min-repeat = non-neg-integer max-repeat = non-neg-integer specific-repetition = non-neg-integer repetition-step = "%" step-size step-size = non-neg-integer integer = "0" / ["-"] pos-integer non-neg-integer = "0" / pos-integer pos-integer = digit1-9 *DIGIT float = [ minus ] int frac [ exp ] ; From RFC 7159 except 'frac' required minus = %x2D ; - plus = %x2B ; + int = zero / ( digit1-9 *DIGIT ) digit1-9 = %x31-39 ; 1-9 frac = decimal-point 1*DIGIT decimal-point = %x2E ; . exp = e [ minus / plus ] 1*DIGIT e = %x65 / %x45 ; e E zero = %x30 ; 0 q-string = quotation-mark *char quotation-mark ; From RFC 7159 char = unescaped / escape ( %x22 / ; " quotation mark U+0022 %x5C / ; \ reverse solidus U+005C %x2F / ; / solidus U+002F %x62 / ; b backspace U+0008 %x66 / ; f form feed U+000C %x6E / ; n line feed U+000A %x72 / ; r carriage return U+000D %x74 / ; t tab U+0009 %x75 4HEXDIG ) ; uXXXX U+XXXX escape = %x5C ; \ quotation-mark = %x22 ; " unescaped = %x20-21 / %x23-5B / %x5D-10FFFF regex = "/" *( escape re-escape-code / not-slash ) "/" [ regex-modifiers ] re-escape-code = %x20-7F ; Specific codes listed elsewhere not-slash = HTAB / CR / LF / %x20-2E / %x30-10FFFF ; Any char except "/" regex-modifiers = *( "i" / "s" / "x" ) uri-scheme = 1*ALPHA ;; Keywords any-kw = %x61.6E.79 ; "any" as-kw = %x61.73 ; "as" base32-kw = %x62.61.73.65.33.32 ; "base32" base32hex-kw = %x62.61.73.65.33.32.68.65.78 ; "base32hex" base64-kw = %x62.61.73.65.36.34 ; "base64" base64url-kw = %x62.61.73.65.36.34.75.72.6C ; "base64url" boolean-kw = %x62.6F.6F.6C.65.61.6E ; "boolean" date-kw = %x64.61.74.65 ; "date" datetime-kw = %x64.61.74.65.74.69.6D.65 ; "datetime" double-kw = %x64.6F.75.62.6C.65 ; "double" email-kw = %x65.6D.61.69.6C ; "email" false-kw = %x66.61.6C.73.65 ; "false" float-kw = %x66.6C.6F.61.74 ; "float" fqdn-kw = %x66.71.64.6E ; "fqdn" hex-kw = %x68.65.78 ; "hex" idn-kw = %x69.64.6E ; "idn" import-kw = %x69.6D.70.6F.72.74 ; "import" int-kw = %x69.6E.74 ; "int" integer-kw = %x69.6E.74.65.67.65.72 ; "integer" ipaddr-kw = %x69.70.61.64.64.72 ; "ipaddr" ipv4-kw = %x69.70.76.34 ; "ipv4" ipv6-kw = %x69.70.76.36 ; "ipv6" jcr-version-kw = %x6A.63.72.2D.76.65.72.73.69.6F.6E ; "jcr-version" not-kw = %x6E.6F.74 ; "not" null-kw = %x6E.75.6C.6C ; "null" phone-kw = %x70.68.6F.6E.65 ; "phone" root-kw = %x72.6F.6F.74 ; "root" ruleset-id-kw = %x72.75.6C.65.73.65.74.2D.69.64 ; "ruleset-id" string-kw = %x73.74.72.69.6E.67 ; "string" time-kw = %x74.69.6D.65 ; "time" true-kw = %x74.72.75.65 ; "true" type-kw = %x74.79.70.65 ; "type" uint-kw = %x75.69.6E.74 ; "uint" unordered-kw = %x75.6E.6F.72.64.65.72.65.64 ; "unordered" uri-kw = %x75.72.69 ; "uri" ;; Referenced RFC 5234 Core Rules ALPHA = %x41-5A / %x61-7A ; A-Z / a-z CR = %x0D ; carriage return DIGIT = %x30-39 ; 0-9 HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" HTAB = %x09 ; horizontal tab LF = %x0A ; linefeed SP = %x20 ; space WSP = SP / HTAB ; white space