; Compositional grammar specification
; v2.4 June 2020
; https://confluence.ihtsdotools.org/display/DOCSCG/5.1+Normative+Specification
;
expression =  ws [definitionStatus ws] subExpression ws
subExpression = focusConcept [ws ":" ws refinement]
definitionStatus = equivalentTo / subtypeOf
equivalentTo = "==="
subtypeOf = "<<<"
focusConcept = conceptReference *(ws "+" ws conceptReference)
conceptReference = conceptId [ws "|" ws  term ws "|"]
conceptId = sctId
term = nonwsNonPipe *( *SP nonwsNonPipe )
refinement = (attributeSet / attributeGroup) *( ws ["," ws] attributeGroup )
attributeGroup = "{" ws attributeSet ws "}"
attributeSet = attribute *(ws "," ws attribute)
attribute = attributeName ws "=" ws attributeValue
attributeName = conceptReference
attributeValue = expressionValue / QM stringValue QM / "#" numericValue / booleanValue
expressionValue = conceptReference / "(" ws subExpression ws ")"
stringValue = 1*(anyNonEscapedChar / escapedChar)
numericValue = ["-"/"+"] (decimalValue / integerValue)
integerValue =  digitNonZero *digit / zero
decimalValue = integerValue "." 1*digit
booleanValue = true / false
true = ("t"/"T") ("r"/"R") ("u"/"U") ("e"/"E")
false = ("f"/"F") ("a"/"A") ("l"/"L") ("s"/"S") ("e"/"E")
sctId = digitNonZero 5*17( digit )
ws = *( SP / HTAB / CR / LF ) ; optional white space
SP = %x20 ; space
HTAB = %x09 ; tab
CR = %x0D ; carriage return
LF = %x0A ; line feed
QM = %x22 ; quotation mark
BS = %x5C ; back slash
digit = %x30-39
zero = %x30
digitNonZero = %x31-39
nonwsNonPipe = %x21-7B / %x7D-7E / UTF8-2 / UTF8-3 / UTF8-4
anyNonEscapedChar = HTAB / CR / LF / %x20-21 / %x23-5B / %x5D-7E / UTF8-2 / UTF8-3 / UTF8-4
escapedChar = BS QM / BS BS
UTF8-2 = %xC2-DF UTF8-tail
UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) / %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) / %xF4 %x80-8F 2( UTF8-tail )
UTF8-tail = %x80-BF