/*
 * Simplified EBNF grammar for ASN.1:90
 *
 * Version:   1.2
 * Date:      10th of August 1999
 * Author:    Per Cederberg, per@percederberg.net
 *
 * This grammar has been extracted from the yacc and lex 
 * sources of 'snacc', a GNU ASN.1 to C or C++ compiler by 
 * Mike Sample.  It has then been modified and cleaned, 
 * making it simpler and more compact. Some additional 
 * types commonly used in Internet MIBs have also been 
 * added.
 */


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

Start ::= ModuleDefinition

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

TagDefault ::= "EXPLICIT" "TAGS"
             | "IMPLICIT" "TAGS"

ModuleIdentifier ::= ModuleReference [ObjectIdentifierValue]

ModuleBody ::= [Exports] [Imports] AssignmentList

Exports ::= "EXPORTS" [SymbolList] ";"

Imports ::= "IMPORTS" [SymbolsFromModuleList] ";"

SymbolsFromModuleList ::= (SymbolsFromModule)+

SymbolsFromModule ::= SymbolList "FROM" ModuleIdentifier

SymbolList ::= Symbol ("," Symbol)*

Symbol ::= TypeReference
         | Identifier
         | DefinedMacroName

AssignmentList ::= (Assignment [";"])+

Assignment ::= TypeAssignment
             | ValueAssignment
             | MacroDefinition

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

MacroBody ::= "BEGIN" <SkipToEND> "END"
            | ModuleReference "." MacroReference

MacroReference ::= TypeReference
                 | DefinedMacroName



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 *  Type Notation Productions
 *
 */

TypeAssignment ::= TypeReference "::=" Type

Type ::= BuiltinType
       | DefinedType
       | DefinedMacroType

BuiltinType ::= "BOOLEAN"
              | "REAL"
              | "NULL"
              | "OBJECT" "IDENTIFIER"
              | IntegerType
              | StringType
              | BitStringType
              | SequenceType
              | SequenceOfType
              | SetType
              | SetOfType
              | ChoiceType
              | EnumeratedType
              | SelectionType
              | TaggedType
              | AnyType

IntegerType ::= "INTEGER" [NamedNumberList | ConstraintList]

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

NamedNumber ::= Identifier "(" (SignedNumber|DefinedValue) ")"

SignedNumber ::= ["-"] Number

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

BitStringType ::= "BIT" "STRING" 
                  [NamedNumberList | ConstraintList]

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

SequenceOfType ::= "SEQUENCE" [SizeConstraint] "OF" Type

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

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

ElementTypeList ::= ElementType ("," ElementType)*

ElementType ::= NamedType 
              | NamedType "OPTIONAL"
              | NamedType "DEFAULT" NamedValue
              | [Identifier] "COMPONENTS" "OF" Type

NamedType ::= [Identifier] Type

ChoiceType ::= "CHOICE" "{" ElementTypeList "}"

EnumeratedType ::= "ENUMERATED" NamedNumberList

SelectionType ::= Identifier "<" Type

TaggedType ::= Tag ["IMPLICIT"|"EXPLICIT"] Type

Tag ::= "[" [Class] ClassNumber "]"

ClassNumber ::= Number
              | DefinedValue

Class ::= "UNIVERSAL"
        | "APPLICATION"
        | "PRIVATE"

AnyType ::= "ANY" ["DEFINED" "BY" Identifier]

DefinedType ::= [ModuleReference "."] TypeReference 
                [ConstraintList]

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

Constraint ::= ValueConstraint
             | SizeConstraint
             | AlphabetConstraint

ValueConstraint ::= Value
                  | ValueRange

ValueRange ::= LowerEndPoint ".." UpperEndPoint

LowerEndPoint ::= (Value|"MIN") ["<"]

UpperEndPoint ::= ["<"] (Value|"MAX")

SizeConstraint ::= "SIZE" "(" ValueConstraint ")"

AlphabetConstraint ::= "FROM" "(" ValueConstraint ")"



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 *  Value Notation Productions
 *
 */

ValueAssignment ::= Identifier Type "::=" Value

Value ::= BuiltinValue
        | DefinedValue

DefinedValue ::= [ModuleReference "."] Identifier

BuiltinValue ::= BooleanValue
               | NullValue
               | SpecialRealValue
               | SignedNumber
               | HexString
               | BinaryString
               | CharString
               | ObjectIdentifierValue

BooleanValue ::= "TRUE"
               | "FALSE"

NullValue ::= "NULL"

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

NamedValue ::= [Identifier] Value

ObjectIdentifierValue ::= "{" ObjIdComponentList "}"

ObjIdComponentList ::= (ObjIdComponent)+

ObjIdComponent ::= Number
                 | Identifier
                 | NameAndNumberForm

NameAndNumberForm := Identifier "(" Number ")"
                   | Identifier "(" DefinedValue ")"

BinaryString ::= "'" <BinaryChars>* "'B"

HexString ::= "'" <HexadecimalChars>* "'H"

CharString ::= """ <StringWithoutSingleDoubleQuote> """

Number ::= <PositiveNumber>

Identifier ::= <LowerCaseFirstIndentifier>

ModuleReference ::= <UpperCaseFirstIdentifier>

TypeReference ::= <UpperCaseFirstIdentifier>



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

DefinedMacroType ::= SnmpObjectTypeMacroType 
                   | SnmpTrapTypeMacroType

DefinedMacroName ::= "OBJECT-TYPE" 
                   | "TRAP-TYPE"

SnmpObjectTypeMacroType ::= "OBJECT-TYPE"
                            "SYNTAX" Type
                            SnmpAccessPart
                            SnmpStatusPart
                            [SnmpDescrPart]
                            [SnmpReferPart]
                            [SnmpIndexPart]
                            [SnmpDefValPart]

SnmpTrapTypeMacroType ::= "TRAP-TYPE" 
                          "ENTERPRISE" Identifier
                          [SnmpVarPart]
                          [SnmpDescrPart]
                          [SnmpReferPart]

SnmpAccessPart ::= "ACCESS" Identifier

SnmpStatusPart ::= "STATUS" Identifier

SnmpDescrPart ::= "DESCRIPTION" CharString

SnmpReferPart ::= "REFERENCE" CharString

SnmpIndexPart ::= "INDEX" "{" TypeOrValueList "}"

TypeOrValueList ::= TypeOrValue ("," TypeOrValue)*

TypeOrValue ::= Type
              | Value

SnmpDefValPart ::= "DEFVAL" "{" Value "}"

SnmpVarPart ::= "VARIABLES" "{" VarTypes "}"

VarTypes ::= Identifier ("," Identifier)*
