/*
 * Mibble MIB Parser (www.mibble.org)
 *
 * See LICENSE.txt for licensing information.
 *
 * Copyright (c) 2004-2017 Per Cederberg. All rights reserved.
 */

%header%

GRAMMARTYPE = "LL"

DESCRIPTION = "A grammar for the ASN.1 format, with SNMP macro extensions. The
               grammar is partly derived from the yacc and lex sources of
               'snacc'--a free ASN.1 to C or C++ compiler. Other parts of the
               grammar comes from RFC 1155, 1212, 1215, 1902, 1903, and 1904.
               This grammar should be able to correctly parse Internet MIBs."

AUTHOR      = "Per Cederberg"
VERSION     = "2.9"
DATE        = "12 March 2009"

LICENSE     = "See LICENSE.txt for licensing information."

COPYRIGHT   = "Copyright (c) 2004-2017 Per Cederberg. All rights reserved."


%tokens%

DOT                          = "."
DOUBLE_DOT                   = ".."
TRIPLE_DOT                   = "..."
COMMA                        = ","
SEMI_COLON                   = ";"
LEFT_PAREN                   = "("
RIGHT_PAREN                  = ")"
LEFT_BRACE                   = "{"
RIGHT_BRACE                  = "}"
LEFT_BRACKET                 = "["
RIGHT_BRACKET                = "]"
MINUS                        = "-"
LESS_THAN                    = "<"
VERTICAL_BAR                 = "|"
DEFINITION                   = "::="

DEFINITIONS                  = "DEFINITIONS"
EXPLICIT                     = "EXPLICIT"
IMPLICIT                     = "IMPLICIT"
TAGS                         = "TAGS"
BEGIN                        = "BEGIN"
END                          = "END"
EXPORTS                      = "EXPORTS"
IMPORTS                      = "IMPORTS"
FROM                         = "FROM"
MACRO                        = "MACRO"

INTEGER                      = "INTEGER"
REAL                         = "REAL"
BOOLEAN                      = "BOOLEAN"
NULL                         = "NULL"
BIT                          = "BIT"
OCTET                        = "OCTET"
STRING                       = "STRING"
ENUMERATED                   = "ENUMERATED"
SEQUENCE                     = "SEQUENCE"
SET                          = "SET"
OF                           = "OF"
CHOICE                       = "CHOICE"
UNIVERSAL                    = "UNIVERSAL"
APPLICATION                  = "APPLICATION"
PRIVATE                      = "PRIVATE"
ANY                          = "ANY"
DEFINED                      = "DEFINED"
BY                           = "BY"
OBJECT                       = "OBJECT"
IDENTIFIER                   = "IDENTIFIER"
INCLUDES                     = "INCLUDES"
MIN                          = "MIN"
MAX                          = "MAX"
SIZE                         = "SIZE"
WITH                         = "WITH"
COMPONENT                    = "COMPONENT"
COMPONENTS                   = "COMPONENTS"
PRESENT                      = "PRESENT"
ABSENT                       = "ABSENT"
OPTIONAL                     = "OPTIONAL"
DEFAULT                      = "DEFAULT"
TRUE                         = "TRUE"
FALSE                        = "FALSE"
PLUS_INFINITY                = "PLUS-INFINITY"
MINUS_INFINITY               = "MINUS-INFINITY"

MODULE_IDENTITY              = "MODULE-IDENTITY"
OBJECT_IDENTITY              = "OBJECT-IDENTITY"
OBJECT_TYPE                  = "OBJECT-TYPE"
NOTIFICATION_TYPE            = "NOTIFICATION-TYPE"
TRAP_TYPE                    = "TRAP-TYPE"
TEXTUAL_CONVENTION           = "TEXTUAL-CONVENTION"
OBJECT_GROUP                 = "OBJECT-GROUP"
NOTIFICATION_GROUP           = "NOTIFICATION-GROUP"
MODULE_COMPLIANCE            = "MODULE-COMPLIANCE"
AGENT_CAPABILITIES           = "AGENT-CAPABILITIES"
LAST_UPDATED                 = "LAST-UPDATED"
ORGANIZATION                 = "ORGANIZATION"
CONTACT_INFO                 = "CONTACT-INFO"
DESCRIPTION                  = "DESCRIPTION"
REVISION                     = "REVISION"
STATUS                       = "STATUS"
REFERENCE                    = "REFERENCE"
SYNTAX                       = "SYNTAX"
BITS                         = "BITS"
UNITS                        = "UNITS"
ACCESS                       = "ACCESS"
MAX_ACCESS                   = "MAX-ACCESS"
MIN_ACCESS                   = "MIN-ACCESS"
INDEX                        = "INDEX"
AUGMENTS                     = "AUGMENTS"
IMPLIED                      = "IMPLIED"
DEFVAL                       = "DEFVAL"
OBJECTS                      = "OBJECTS"
ENTERPRISE                   = "ENTERPRISE"
VARIABLES                    = "VARIABLES"
DISPLAY_HINT                 = "DISPLAY-HINT"
NOTIFICATIONS                = "NOTIFICATIONS"
MODULE                       = "MODULE"
MANDATORY_GROUPS             = "MANDATORY-GROUPS"
GROUP                        = "GROUP"
WRITE_SYNTAX                 = "WRITE-SYNTAX"
PRODUCT_RELEASE              = "PRODUCT-RELEASE"
SUPPORTS                     = "SUPPORTS"
VARIATION                    = "VARIATION"
CREATION_REQUIRES            = "CREATION-REQUIRES"

BINARY_STRING                = <<'[0-1]*'(B|b)>>
HEXADECIMAL_STRING           = <<'[0-9A-Fa-f]*'(H|h)>>
QUOTED_STRING                = <<"([^"]|"")*">>
IDENTIFIER_STRING            = <<[a-zA-Z][a-zA-Z0-9-_]*>>
NUMBER_STRING                = <<[0-9]+>>

WHITESPACE                   = <<[ \t\n\r\f\x0b\x17\x18\x19\x1a]+>> %ignore%
COMMENT                      = <<--([^\n\r-]|-[^\n\r-])*(--|-?[\n\r])>> %ignore%


%productions%

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 *  Module def/import/export productions
 *
 */

Start = ModuleDefinition+ ;

ModuleDefinition = ModuleIdentifier "DEFINITIONS" [TagDefault]
                   "::=" "BEGIN" [ModuleBody] "END" ;

ModuleIdentifier = IDENTIFIER_STRING [ObjectIdentifierValue] ;

ModuleReference = IDENTIFIER_STRING "." ;

TagDefault = "EXPLICIT" "TAGS"
           | "IMPLICIT" "TAGS" ;

ModuleBody = [ExportList] [ImportList] AssignmentList ;

ExportList = "EXPORTS" [SymbolList] ";" ;

ImportList = "IMPORTS" SymbolsFromModule* ";" ;

SymbolsFromModule = SymbolList "FROM" ModuleIdentifier ;

SymbolList = Symbol ("," Symbol)* ;

Symbol = IDENTIFIER_STRING
       | DefinedMacroName ;

AssignmentList = Assignment+ ;

Assignment = MacroDefinition [";"]
           | TypeAssignment [";"]
           | ValueAssignment [";"] ;

MacroDefinition = MacroReference "MACRO" "::=" MacroBody ;

MacroReference = IDENTIFIER_STRING
               | DefinedMacroName ;

MacroBody = "BEGIN" MacroBodyElement* "END"
          | ModuleReference MacroReference ;

MacroBodyElement = "("
                 | ")"
                 | "|"
                 | "::="
                 | "INTEGER"
                 | "REAL"
                 | "BOOLEAN"
                 | "NULL"
                 | "BIT"
                 | "OCTET"
                 | "STRING"
                 | "OBJECT"
                 | "IDENTIFIER"
                 | IDENTIFIER_STRING
                 | QUOTED_STRING ;



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 *  Type notation productions
 *
 */

TypeAssignment = IDENTIFIER_STRING "::=" Type ;

Type = BuiltinType
     | DefinedType
     | DefinedMacroType ;

DefinedType = [ModuleReference] IDENTIFIER_STRING [ValueOrConstraintList] ;

BuiltinType = NullType
            | BooleanType
            | RealType
            | IntegerType
            | ObjectIdentifierType
            | StringType
            | BitStringType
            | BitsType
            | SequenceType
            | SequenceOfType
            | SetType
            | SetOfType
            | ChoiceType
            | EnumeratedType
            | SelectionType
            | TaggedType
            | AnyType ;

NullType = "NULL" ;

BooleanType = "BOOLEAN" ;

RealType = "REAL" ;

IntegerType = "INTEGER" [ValueOrConstraintList] ;

ObjectIdentifierType = "OBJECT" "IDENTIFIER" ;

StringType = "OCTET" "STRING" [ConstraintList] ;

BitStringType = "BIT" "STRING" [ValueOrConstraintList] ;

BitsType = "BITS" [ValueOrConstraintList] ;

SequenceType = "SEQUENCE" "{" [ElementTypeList] "}" ;

SequenceOfType = "SEQUENCE" [ConstraintList] "OF" Type ;

SetType = "SET" "{" [ElementTypeList] "}" ;

SetOfType = "SET" [SizeConstraint] "OF" Type ;

ChoiceType = "CHOICE" "{" ElementTypeList "}" ;

EnumeratedType = "ENUMERATED" NamedNumberList ;

SelectionType = IDENTIFIER_STRING "<" Type ;

TaggedType = Tag [ExplicitOrImplicitTag] Type ;

Tag = "[" [Class] NUMBER_STRING "]" ;

Class = "UNIVERSAL"
      | "APPLICATION"
      | "PRIVATE" ;

ExplicitOrImplicitTag = "EXPLICIT"
                      | "IMPLICIT" ;

AnyType = "ANY"
        | "ANY" "DEFINED" "BY" IDENTIFIER_STRING ;

ElementTypeList = ElementType ("," ElementType)* ;

ElementType = [IDENTIFIER_STRING] Type [OptionalOrDefaultElement]
            | [IDENTIFIER_STRING] "COMPONENTS" "OF" Type ;

OptionalOrDefaultElement = "OPTIONAL"
                         | "DEFAULT" [IDENTIFIER_STRING] Value ;

ValueOrConstraintList = NamedNumberList
                      | ConstraintList ;

NamedNumberList = "{" NamedNumber ("," NamedNumber)* "}" ;

NamedNumber = IDENTIFIER_STRING "(" Number ")" ;

Number = NumberValue
       | BinaryValue
       | HexadecimalValue
       | DefinedValue ;

ConstraintList = "(" Constraint ("|" Constraint)* ")" ;

Constraint = ValueConstraint
           | SizeConstraint
           | AlphabetConstraint
           | ContainedTypeConstraint
           | InnerTypeConstraint ;

ValueConstraintList = "(" ValueConstraint ("|" ValueConstraint)* ")" ;

ValueConstraint = LowerEndPoint [ValueRange] ;

ValueRange = ["<"] ".." ["<"] UpperEndPoint;

LowerEndPoint = Value
              | "MIN" ;

UpperEndPoint = Value
              | "MAX" ;

SizeConstraint = "SIZE" ValueConstraintList ;

AlphabetConstraint = "FROM" ValueConstraintList ;

ContainedTypeConstraint = "INCLUDES" Type ;

InnerTypeConstraint = "WITH" "COMPONENT" ValueOrConstraintList
                    | "WITH" "COMPONENTS" ComponentsList ;

ComponentsList = "{" ComponentConstraint ComponentsListTail* "}"
               | "{" "..." ComponentsListTail+ "}" ;

ComponentsListTail = "," [ComponentConstraint] ;

ComponentConstraint = IDENTIFIER_STRING [ComponentValuePresence]
                    | ComponentValuePresence ;

ComponentValuePresence = ValueOrConstraintList [ComponentPresence]
                       | ComponentPresence ;

ComponentPresence = "PRESENT"
                  | "ABSENT"
                  | "OPTIONAL" ;



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 *  Value notation productions
 *
 */

ValueAssignment = IDENTIFIER_STRING Type "::=" Value ;

Value = BuiltinValue
      | DefinedValue ;

DefinedValue = [ModuleReference] IDENTIFIER_STRING ;

BuiltinValue = NullValue
             | BooleanValue
             | SpecialRealValue
             | NumberValue
             | BinaryValue
             | HexadecimalValue
             | StringValue
             | BitOrObjectIdentifierValue ;

NullValue = "NULL" ;

BooleanValue = "TRUE"
             | "FALSE" ;

SpecialRealValue = "PLUS-INFINITY"
                 | "MINUS-INFINITY" ;

NumberValue = ["-"] NUMBER_STRING ;

BinaryValue = BINARY_STRING ;

HexadecimalValue = HEXADECIMAL_STRING ;

StringValue = QUOTED_STRING ;

BitOrObjectIdentifierValue = NameValueList ;

BitValue = NameValueList ;

ObjectIdentifierValue = NameValueList ;

NameValueList = "{" NameValueComponent* "}" ;

NameValueComponent = [","] NameOrNumber ;

NameOrNumber = NUMBER_STRING
             | IDENTIFIER_STRING
             | NameAndNumber ;

NameAndNumber = IDENTIFIER_STRING "(" NUMBER_STRING ")"
              | IDENTIFIER_STRING "(" DefinedValue ")" ;



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 *  Macro Syntax definitions
 *
 */

DefinedMacroType = SnmpModuleIdentityMacroType
                 | SnmpObjectIdentityMacroType
                 | SnmpObjectTypeMacroType
                 | SnmpNotificationTypeMacroType
                 | SnmpTrapTypeMacroType
                 | SnmpTextualConventionMacroType
                 | SnmpObjectGroupMacroType
                 | SnmpNotificationGroupMacroType
                 | SnmpModuleComplianceMacroType
                 | SnmpAgentCapabilitiesMacroType ;

DefinedMacroName = "MODULE-IDENTITY"
                 | "OBJECT-IDENTITY"
                 | "OBJECT-TYPE"
                 | "NOTIFICATION-TYPE"
                 | "TRAP-TYPE"
                 | "TEXTUAL-CONVENTION"
                 | "OBJECT-GROUP"
                 | "NOTIFICATION-GROUP"
                 | "MODULE-COMPLIANCE"
                 | "AGENT-CAPABILITIES" ;

SnmpModuleIdentityMacroType = "MODULE-IDENTITY"
                              SnmpUpdatePart
                              SnmpOrganizationPart
                              SnmpContactPart
                              SnmpDescrPart
                              SnmpRevisionPart* ;

SnmpObjectIdentityMacroType = "OBJECT-IDENTITY"
                              SnmpStatusPart
                              SnmpDescrPart
                              [SnmpReferPart] ;

SnmpObjectTypeMacroType = "OBJECT-TYPE"
                          SnmpSyntaxPart
                          [SnmpUnitsPart]
                          SnmpAccessPart
                          SnmpStatusPart
                          [SnmpDescrPart]
                          [SnmpReferPart]
                          [SnmpIndexPart]
                          [SnmpDefValPart] ;

SnmpNotificationTypeMacroType = "NOTIFICATION-TYPE"
                                [SnmpObjectsPart]
                                SnmpStatusPart
                                SnmpDescrPart
                                [SnmpReferPart] ;

SnmpTrapTypeMacroType = "TRAP-TYPE"
                        SnmpEnterprisePart
                        [SnmpVarPart]
                        [SnmpDescrPart]
                        [SnmpReferPart] ;

SnmpTextualConventionMacroType = "TEXTUAL-CONVENTION"
                                 [SnmpDisplayPart]
                                 SnmpStatusPart
                                 SnmpDescrPart
                                 [SnmpReferPart]
                                 SnmpSyntaxPart ;

SnmpObjectGroupMacroType = "OBJECT-GROUP"
                           SnmpObjectsPart
                           SnmpStatusPart
                           SnmpDescrPart
                           [SnmpReferPart] ;

SnmpNotificationGroupMacroType = "NOTIFICATION-GROUP"
                                 SnmpNotificationsPart
                                 SnmpStatusPart
                                 SnmpDescrPart
                                 [SnmpReferPart] ;

SnmpModuleComplianceMacroType = "MODULE-COMPLIANCE"
                                SnmpStatusPart
                                SnmpDescrPart
                                [SnmpReferPart]
                                SnmpModulePart+ ;

SnmpAgentCapabilitiesMacroType = "AGENT-CAPABILITIES"
                                 SnmpProductReleasePart
                                 SnmpStatusPart
                                 SnmpDescrPart
                                 [SnmpReferPart]
                                 SnmpModuleSupportPart* ;

SnmpUpdatePart = "LAST-UPDATED" QUOTED_STRING ;

SnmpOrganizationPart = "ORGANIZATION" QUOTED_STRING ;

SnmpContactPart = "CONTACT-INFO" QUOTED_STRING ;

SnmpDescrPart = "DESCRIPTION" QUOTED_STRING ;

SnmpRevisionPart = "REVISION" Value
                   "DESCRIPTION" QUOTED_STRING ;

SnmpStatusPart = "STATUS" IDENTIFIER_STRING ;

SnmpReferPart = "REFERENCE" QUOTED_STRING ;

SnmpSyntaxPart = "SYNTAX" Type ;

SnmpUnitsPart = "UNITS" QUOTED_STRING ;

SnmpAccessPart = "ACCESS" IDENTIFIER_STRING
               | "MAX-ACCESS" IDENTIFIER_STRING
               | "MIN-ACCESS" IDENTIFIER_STRING ;

SnmpIndexPart = "INDEX" "{" IndexValueList "}"
              | "AUGMENTS" "{" Value "}" ;

IndexValueList = IndexValue ("," IndexValue)* ;

IndexValue = Value
           | "IMPLIED" Value
           | IndexType ;

IndexType = IntegerType
          | StringType
          | ObjectIdentifierType ;

SnmpDefValPart = "DEFVAL" "{" Value "}" ;

SnmpObjectsPart = "OBJECTS" "{" ValueList "}" ;

ValueList = Value ("," Value)* ;

SnmpEnterprisePart = "ENTERPRISE" Value ;

SnmpVarPart = "VARIABLES" "{" ValueList "}" ;

SnmpDisplayPart = "DISPLAY-HINT" QUOTED_STRING ;

SnmpNotificationsPart = "NOTIFICATIONS" "{" ValueList "}" ;

SnmpModulePart = "MODULE" [SnmpModuleImport]
                 [SnmpMandatoryPart]
                 SnmpCompliancePart* ;

SnmpModuleImport = ModuleIdentifier ;

SnmpMandatoryPart = "MANDATORY-GROUPS" "{" ValueList "}" ;

SnmpCompliancePart = ComplianceGroup
                   | ComplianceObject ;

ComplianceGroup = "GROUP" Value
                  SnmpDescrPart ;

ComplianceObject = "OBJECT" Value
                   [SnmpSyntaxPart]
                   [SnmpWriteSyntaxPart]
                   [SnmpAccessPart]
                   SnmpDescrPart ;

SnmpWriteSyntaxPart = "WRITE-SYNTAX" Type ;

SnmpProductReleasePart = "PRODUCT-RELEASE" QUOTED_STRING ;

SnmpModuleSupportPart = "SUPPORTS" SnmpModuleImport
                        "INCLUDES" "{" ValueList "}"
                        SnmpVariationPart* ;

SnmpVariationPart = "VARIATION" Value
                    [SnmpSyntaxPart]
                    [SnmpWriteSyntaxPart]
                    [SnmpAccessPart]
                    [SnmpCreationPart]
                    [SnmpDefValPart]
                    SnmpDescrPart ;

SnmpCreationPart = "CREATION-REQUIRES" "{" ValueList "}" ;
