;;
;; sming.abnf -- SMIng grammar in ABNF notation (RFC 2234).
;;
;; @(#) $Id: sming.abnf,v 1.22 1999/04/20 18:06:07 strauss Exp $
;;
;; Copyright (C) The Internet Society (1999). All Rights Reserved.
;;

smingFile               = optsep *(moduleStatement optsep)

;;
;; Statement rules.
;;

moduleStatement         = moduleKeyword sep ucIdentifier sep
                              lcIdentifier optsep "{" stmtsep
                              *(importStatement stmtsep)
                              oidStatement stmtsep
                              organizationStatement stmtsep
                              contactStatement stmtsep
                              descriptionStatement stmtsep
                              *1(referenceStatement stmtsep)
                              1*(revisionStatement stmtsep)
                              *(extensionStatement stmtsep)
                              *(typedefStatement stmtsep)
                              *(anyObjectStatement stmtsep)
                              *(notificationStatement stmtsep)
                              *(groupStatement stmtsep)
                              *(complianceStatement stmtsep)
                          "}" optsep ";"

extensionStatement      = extensionKeyword sep lcIdentifier optsep
                              "{" stmtsep
                              *1(statusStatement stmtsep)
                              descriptionStatement stmtsep
                              *1(referenceStatement stmtsep)
                          "}" optsep ";"

typedefStatement        = typedefKeyword sep ucIdentifier optsep
                              "{" stmtsep
                              typedefTypeStatement stmtsep
                              *1(defaultStatement stmtsep)
                              *1(formatStatement stmtsep)
                              *1(unitsStatement stmtsep)
                              *1(statusStatement stmtsep)
                              descriptionStatement stmtsep
                              *1(referenceStatement stmtsep)
                          "}" optsep ";"

anyObjectStatement      = nodeStatement /
                          scalarStatement /
                          tableStatement

nodeStatement           = nodeKeyword sep lcIdentifier optsep
                              "{" stmtsep
                              oidStatement stmtsep
                              *1(statusStatement stmtsep)
                              *1(descriptionStatement stmtsep)
                              *1(referenceStatement stmtsep)
                          "}" optsep ";"

scalarStatement         = scalarKeyword sep lcIdentifier optsep
                              "{" stmtsep
                              oidStatement stmtsep
                              typeStatement stmtsep
                              accessStatement stmtsep
                              *1(defaultStatement stmtsep)
                              *1(formatStatement stmtsep)
                              *1(unitsStatement stmtsep)
                              *1(statusStatement stmtsep)
                              descriptionStatement stmtsep
                              *1(referenceStatement stmtsep)
                          "}" optsep ";"

tableStatement          = tableKeyword sep lcIdentifier optsep
                              "{" stmtsep
                              oidStatement stmtsep
                              *1(statusStatement stmtsep)
                              descriptionStatement stmtsep
                              *1(referenceStatement stmtsep)
                              rowStatement stmtsep
                          "}" optsep ";"

rowStatement            = rowKeyword sep lcIdentifier optsep
                              "{" stmtsep
                              oidStatement stmtsep
                              anyIndexStatement stmtsep
                              *1(createStatement stmtsep)
                              *1(statusStatement stmtsep)
                              descriptionStatement stmtsep
                              *1(referenceStatement stmtsep)
                              1*(columnStatement stmtsep)
                          "}" optsep ";"

columnStatement         = columnKeyword sep lcIdentifier optsep
                              "{" stmtsep
                              oidStatement stmtsep
                              typeStatement stmtsep
                              accessStatement stmtsep
                              *1(defaultStatement stmtsep)
                              *1(formatStatement stmtsep)
                              *1(unitsStatement stmtsep)
                              *1(statusStatement stmtsep)
                              descriptionStatement stmtsep
                              *1(referenceStatement stmtsep)
                          "}" optsep ";"

notificationStatement   = notificationKeyword sep lcIdentifier
                              optsep "{" stmtsep
                              oidStatement stmtsep
                              *1(objectsStatement stmtsep)
                              *1(statusStatement stmtsep)
                              descriptionStatement stmtsep
                              *1(referenceStatement stmtsep)
                          "}" optsep ";"

groupStatement          = groupKeyword sep lcIdentifier optsep
                              "{" stmtsep
                              oidStatement stmtsep
                              membersStatement stmtsep
                              *1(statusStatement stmtsep)
                              descriptionStatement stmtsep
                              *1(referenceStatement stmtsep)
                          "}" optsep ";"

complianceStatement     = complianceKeyword sep lcIdentifier optsep
                              "{" stmtsep
                              oidStatement stmtsep
                              *1(statusStatement stmtsep)
                              descriptionStatement stmtsep
                              *1(referenceStatement stmtsep)
                              *1(mandatoryStatement stmtsep)
                              *(optionalStatement stmtsep)
                              *(refineStatement stmtsep)
                          "}" optsep ";"

importStatement         = importKeyword sep ucIdentifier optsep
                              "(" optsep
                              identifierList optsep
                          ")" optsep ";"

revisionStatement       = revisionKeyword optsep "{" stmtsep
                              dateStatement stmtsep
                              descriptionStatement stmtsep
                          "}" optsep ";"

typedefTypeStatement    = typeKeyword sep refinedBaseType optsep ";"

typeStatement           = typeKeyword sep
                              (refinedBaseType / refinedType)
                              optsep ";"

writetypeStatement      = writetypeKeyword sep
                              (refinedBaseType / refinedType)
                              optsep ";"

anyIndexStatement       = indexStatement /
                          augmentsStatement /
                          reordersStatement /
                          sparseStatement /
                          expandsStatement

indexStatement          = indexKeyword *1(sep impliedKeyword) optsep
                              "(" optsep qlcIdentifierList
                              optsep ")" optsep ";"

augmentsStatement       = augmentsKeyword sep qlcIdentifier
                              optsep ";"

reordersStatement       = reordersKeyword sep qlcIdentifier 
                              *1(sep impliedKeyword)
                              optsep "(" optsep
                              qlcIdentifierList optsep ")"
                              optsep ";"

sparseStatement         = sparseKeyword sep qlcIdentifier optsep ";"

expandsStatement        = expandsKeyword sep qlcIdentifier
                              *1(sep impliedKeyword)
                              optsep "(" optsep
                              qlcIdentifierList optsep ")"
                              optsep ";"

createStatement         = createKeyword *1(optsep createColumns)
                              optsep ";"

createColumns           = "(" optsep qlcIdentifierList optsep ")"

oidStatement            = oidKeyword sep objectIdentifier optsep ";"

dateStatement           = dateKeyword sep date optsep ";"

organizationStatement   = organizationKeyword sep text optsep ";"

contactStatement        = contactKeyword sep text optsep ";"

formatStatement         = formatKeyword sep format optsep ";"

unitsStatement          = unitsKeyword sep units optsep ";"

statusStatement         = statusKeyword sep status optsep ";"

accessStatement         = accessKeyword sep access optsep ";"

defaultStatement        = defaultKeyword sep anyValue optsep ";"

descriptionStatement    = descriptionKeyword sep text optsep ";"

referenceStatement      = referenceKeyword sep text optsep ";"

membersStatement        = membersKeyword optsep "(" optsep
                              qlcIdentifierList optsep
                              ")" optsep ";"

objectsStatement        = objectsKeyword optsep "(" optsep
                              qlcIdentifierList optsep
                              ")" optsep ";"

mandatoryStatement      = mandatoryKeyword optsep "(" optsep
                              qlcIdentifierList optsep
                              ")" optsep ";"

optionalStatement       = optionalKeyword sep qlcIdentifier optsep
                              "{" descriptionStatement stmtsep
                          "}" optsep ";"

refineStatement         = refineKeyword sep qlcIdentifier optsep "{"
                              *1(typeStatement stmtsep)
                              *1(writetypeStatement stmtsep)
                              *1(accessStatement stmtsep)
                              descriptionStatement stmtsep
                          "}" optsep ";"

;;
;;
;;

refinedBaseType         = OctetStringKeyword *1(optsep numberSpec) /
                          ObjectIdentifierKeyword /
                          Integer32Keyword *1(optsep numberSpec) /
                          Unsigned32Keyword *1(optsep numberSpec) /
                          Integer64Keyword *1(optsep numberSpec) /
                          Unsigned64Keyword *1(optsep numberSpec) /
                          Float32Keyword *1(optsep floatSpec) /
                          Float64Keyword *1(optsep floatSpec) /
                          Float128Keyword *1(optsep floatSpec) /
                          EnumerationKeyword namedNumberSpec /
                          BitsKeyword namedNumberSpec 

refinedType             = qucIdentifier *1(optsep anySpec)

anySpec                 = numberSpec / floatSpec

numberSpec              = "(" optsep numberElement
                              *furtherNumberElement
                              optsep ")"

furtherNumberElement    = optsep "|" optsep numberElement

numberElement           = signedNumber *1numberUpperLimit

numberUpperLimit        = optsep ".." optsep signedNumber

floatSpec               = "(" optsep floatElement
                              *furtherFloatElement
                              optsep ")"

furtherFloatElement     = optsep "|" optsep floatElement

floatElement            = floatValue *1floatUpperLimit

floatUpperLimit         = optsep ".." optsep floatValue

namedNumberSpec         = "(" optsep namedNumberList optsep ")"

namedNumberList         = namedNumberItem
                              *(optsep "," optsep namedNumberItem)
                              *1(optsep ",")

namedNumberItem         = lcIdentifier optsep "(" optsep number
                              optsep ")"

identifierList          = identifier
                              *(optsep "," optsep identifier)
                              *1(optsep ",")

qIdentifierList         = qIdentifier
                              *(optsep "," optsep qIdentifier)
                              *1(optsep ",")

qlcIdentifierList       = qlcIdentifier 
                              *(optsep "," optsep qlcIdentifier)
                              *1(optsep ",")

bitsValue               = "(" optsep bitsList optsep ")"

bitsList                = *1(lcIdentifier 
                              *(optsep "," optsep lcIdentifier))
                              *1(optsep ",")

;;
;; Other basic rules.
;;

identifier              = ucIdentifier / lcIdentifier

qIdentifier             = qucIdentifier / qlcIdentifier

ucIdentifier            = ucAlpha *63(ALPHA / DIGIT / "-")

qucIdentifier           = *1(ucIdentifier "::") ucIdentifier

lcIdentifier            = lcAlpha *63(ALPHA / DIGIT / "-")

qlcIdentifier           = *1(ucIdentifier "::") lcIdentifier

text                    = textSegment *(optsep textSegment)

textSegment             = DQUOTE *textAtom DQUOTE

textAtom                = textVChar / HTAB / SP / lineBreak

date                    = DQUOTE 4DIGIT "-" 2DIGIT "-" 2DIGIT
                              *1(" " 2DIGIT ":" 2DIGIT)
                              DQUOTE
                          ; always in UTC

format                  = textSegment

units                   = textSegment

anyValue                = bitsValue /
                          negativeNumber /
                          hexadecimalNumber /
                          floatValue /
                          text /
                          objectIdentifier
                          ; Note: `objectIdentifer' includes the
                          ; syntax of enumeration labels and postive
                          ; numbers. They are not named literally to
                          ; avoid reduce/reduce conflicts when
                          ; building LR parsers based on this   
                          ; grammar.

status                  = currentKeyword /
                          deprecatedKeyword /
                          obsoleteKeyword

access                  = noaccessKeyword /
                          notifyonlyKeyword /
                          readonlyKeyword /
                          readwriteKeyword

objectIdentifier        = (qlcIdentifier / subid) *127("." subid)

subid                   = decimalNumber

number                  = hexadecimalNumber / decimalNumber

negativeNumber          = "-" decimalNumber

signedNumber            = number / negativeNumber

decimalNumber           = "0" / (nonZeroDigit *DIGIT)

zeroDecimalNumber       = 1*DIGIT

hexadecimalNumber       = "0x" 1*(HEXDIG HEXDIG)

floatValue              = neginfKeyword / 
                          posinfKeyword /
                          snanKeyword / 
                          qnanKeyword /
                          signedNumber "." zeroDecimalNumber
                              *1("E" ("+"/"-") zeroDecimalNumber)

;;
;; Rules to skip unknown statements
;; with arbitrary arguments and blocks.
;;

unknownStatement        = unknownKeyword optsep *unknownArgument
                              optsep ";"

unknownArgument         = ("(" optsep unknownList optsep ")") /
                          ("{" optsep *unknownStatement optsep "}") /
                          qucIdentifier / 
                          anyValue /
                          anySpec

unknownList             = namedNumberList / 
                          qIdentifierList

unknownKeyword          = lcIdentifier

;;
;; Keyword rules.
;;
;; Typically, keywords are represented by tokens returned from the
;; lexical analyzer.  Note, that the lexer has to be stateful to
;; distinguish keywords from identifiers depending on the context
;; position in the input stream.
;;
;; Also note, that these keyword definitions are represented in
;; cleartext for readability, while SMIng keywords are meant to be
;; case-sensitive, although ABNF makes quoted strings like these to
;; be case-insensitive.
;;

;; Statement keywords.

moduleKeyword           = "module"
importKeyword           = "import"
revisionKeyword         = "revision"
oidKeyword              = "oid"
dateKeyword             = "date"
organizationKeyword     = "organization"
contactKeyword          = "contact"
descriptionKeyword      = "description"
referenceKeyword        = "reference"
extensionKeyword        = "extension"
typedefKeyword          = "typedef"
typeKeyword             = "type"
writetypeKeyword        = "writetype"
nodeKeyword             = "node"
scalarKeyword           = "scalar"
tableKeyword            = "table"
columnKeyword           = "column"
rowKeyword              = "row"
notificationKeyword     = "notification"
groupKeyword            = "group"
complianceKeyword       = "compliance"
formatKeyword           = "format"
unitsKeyword            = "units"
statusKeyword           = "status"
accessKeyword           = "access"
defaultKeyword          = "default"
impliedKeyword          = "implied"
indexKeyword            = "index"
augmentsKeyword         = "augments"
reordersKeyword         = "reorders"
sparseKeyword           = "sparse"
expandsKeyword          = "expands"
createKeyword           = "create"
membersKeyword          = "members"
objectsKeyword          = "objects"
mandatoryKeyword        = "mandatory"
optionalKeyword         = "optional"
refineKeyword           = "refine"

;; Base type keywords.

OctetStringKeyword      = "OctetString"
ObjectIdentifierKeyword = "ObjectIdentifier"
Integer32Keyword        = "Integer32"
Unsigned32Keyword       = "Unsigned32"
Integer64Keyword        = "Integer64"
Unsigned64Keyword       = "Unsigned64"
Float32Keyword          = "Float32"
Float64Keyword          = "Float64"
Float128Keyword         = "Float128"
BitsKeyword             = "Bits"
EnumerationKeyword      = "Enumeration"

;; Status keyword.

currentKeyword          = "current"
deprecatedKeyword       = "deprecated"
obsoleteKeyword         = "obsolete"

;; Access keywords.

noaccessKeyword         = "noaccess"
notifyonlyKeyword       = "notifyonly"
readonlyKeyword         = "readonly"
readwriteKeyword        = "readwrite"

;; Special floating point values' keywords.

neginfKeyword           = "neginf"
posinfKeyword           = "posinf"
snanKeyword             = "snan"
qnanKeyword             = "qnan"

;;
;; Some low level rules.
;; These tokens are typically skipped by the lexical analyzer.
;;

sep                     = 1*(comment / lineBreak / WSP)
                          ; unconditional separator

optsep                  = *(comment / lineBreak / WSP)

stmtsep                 = *(comment /
                            lineBreak /
                            WSP /
                            unknownStatement)

comment                 = "//" *(WSP / VCHAR) lineBreak 

lineBreak               = CRLF / LF

;;
;; Encoding specific rules.
;;

textVChar               = %x21 / %x23-7E
                          ; any VCHAR except DQUOTE

ucAlpha                 = %x41-5A

lcAlpha                 = %x61-7A

nonZeroDigit            = %x31-39

;;
;; RFC 2234 core rules.
;;

ALPHA          =  %x41-5A / %x61-7A
                       ; A-Z / a-z

CR             =  %x0D
                       ; carriage return

CRLF           =  CR LF
                       ; Internet standard newline

DIGIT          =  %x30-39
                       ; 0-9

DQUOTE         =  %x22
                       ; " (Double Quote)

HEXDIG         =  DIGIT / "A" / "B" / "C" / "D" / "E" / "F"

HTAB           =  %x09
                       ; horizontal tab

LF             =  %x0A
                       ; linefeed

SP             =  %x20
                       ; space

VCHAR          =  %x21-7E
                       ; visible (printing) characters

WSP            =  SP / HTAB
                       ; white space

;;
;; EOF
;;