def METHOD_NAME():
    global bnf
    if not bnf:
        # punctuation
        (
            colon,
            lbrace,
            rbrace,
            lbrack,
            rbrack,
            lparen,
            rparen,
            equals,
            comma,
            dot,
            slash,
            bslash,
            star,
            semi,
            langle,
            rangle,
        ) = map(Literal, r":{}[]()=,./\*;<>")
        # keywords
        (
            any_,
            attribute_,
            boolean_,
            case_,
            char_,
            const_,
            context_,
            default_,
            double_,
            enum_,
            exception_,
            FALSE_,
            fixed_,
            float_,
            inout_,
            interface_,
            in_,
            long_,
            module_,
            Object_,
            octet_,
            oneway_,
            out_,
            raises_,
            readonly_,
            sequence_,
            short_,
            string_,
            struct_,
            switch_,
            TRUE_,
            typedef_,
            unsigned_,
            union_,
            void_,
            wchar_,
            wstring_,
        ) = map(
            Keyword,
            """any attribute boolean case char const context
            default double enum exception FALSE fixed float inout interface in long module
            Object octet oneway out raises readonly sequence short string struct switch
            TRUE typedef unsigned union void wchar wstring""".split(),
        )
        identifier = Word(alphas, alphanums + "_").setName("identifier")
        real = Regex(r"[+-]?\d+\.\d*([Ee][+-]?\d+)?").setName("real")
        integer = Regex(r"0x[0-9a-fA-F]+|[+-]?\d+").setName("int")
        udTypeName = delimitedList(identifier, "::", combine=True).setName("udType")
        typeName = (
            any_
            | boolean_
            | char_
            | double_
            | fixed_
            | float_
            | long_
            | octet_
            | short_
            | string_
            | wchar_
            | wstring_
            | udTypeName
        ).setName("type")
        sequenceDef = Forward().setName("seq")
        sequenceDef << Group(sequence_ + langle + (sequenceDef | typeName) + rangle)
        typeDef = sequenceDef | (typeName + Optional(lbrack + integer + rbrack))
        typedefDef = Group(typedef_ + typeDef + identifier + semi).setName("typedef")
        moduleDef = Forward().setName("moduleDef")
        constDef = Group(
            const_
            + typeDef
            + identifier
            + equals
            + (real | integer | quotedString)
            + semi
        ).setName(
            "constDef"
        )  # | quotedString )
        exceptionItem = Group(typeDef + identifier + semi)
        exceptionDef = (
            exception_ + identifier + lbrace + ZeroOrMore(exceptionItem) + rbrace + semi
        ).setName("exceptionDef")
        attributeDef = Optional(readonly_) + attribute_ + typeDef + identifier + semi
        paramlist = delimitedList(
            Group((inout_ | in_ | out_) + typeName + identifier)
        ).setName("paramlist")
        operationDef = (
            (void_ ^ typeDef)
            + identifier
            + lparen
            + Optional(paramlist)
            + rparen
            + Optional(raises_ + lparen + Group(delimitedList(typeName)) + rparen)
            + semi
        ).setName("operationDef")
        interfaceItem = constDef | exceptionDef | attributeDef | operationDef
        interfaceDef = Group(
            interface_
            + identifier
            + Optional(colon + delimitedList(typeName))
            + lbrace
            + ZeroOrMore(interfaceItem)
            + rbrace
            + semi
        ).setName("interfaceDef")
        moduleItem = (
            interfaceDef | exceptionDef | constDef | typedefDef | moduleDef
        ).setName("moduleItem")
        (
            moduleDef
            << module_ + identifier + lbrace + ZeroOrMore(moduleItem) + rbrace + semi
        )
        bnf = moduleDef | OneOrMore(moduleItem)
        singleLineComment = "//" + restOfLine
        bnf.ignore(singleLineComment)
        bnf.ignore(cStyleComment)
    return bnf