예제 #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        /// <remarks>
        ///
        /// See http://www.dmtf.org/sites/default/files/standards/documents/DSP0221_3.0.0a.pdf
        /// A.12 Parameter declaration
        ///
        ///     parameterDeclaration = [ qualifierList ] ( primitiveParamDeclaration /
        ///                            complexParamDeclaration /
        ///                            enumParamDeclaration /
        ///                            referenceParamDeclaration )
        ///
        ///     primitiveParamDeclaration = primitiveType parameterName [ array ]
        ///                                 [ "=" primitiveTypeValue ]
        ///     complexParamDeclaration   = structureOrClassName parameterName [ array ]
        ///                                 [ "=" ( complexTypeValue / aliasIdentifier ) ]
        ///     enumParamDeclaration      = enumName parameterName [ array ]
        ///                                 [ "=" enumValue ]
        ///     referenceParamDeclaration = classReference parameterName [ array ]
        ///                                 [ "=" referenceTypeValue ]
        ///
        ///     parameterName = IDENTIFIER
        ///
        /// </remarks>
        internal static ParameterDeclarationAst Parse(ParserStream stream)
        {
            var parameter  = new ParameterDeclarationAst();
            var qualifiers = default(QualifierListAst);

            if (stream.Peek <AttributeOpenToken>() != null)
            {
                qualifiers = QualifierListAst.Parse(stream);
            }
            parameter.Qualifiers = qualifiers;
            parameter.Type       = stream.Read <IdentifierToken>();
            if (stream.PeekIdentifier(Keywords.REF))
            {
                stream.ReadIdentifier(Keywords.REF);
                parameter.IsRef = true;
            }
            else
            {
                parameter.IsRef = false;
            }
            parameter.Name = stream.Read <IdentifierToken>();
            if (stream.Peek <AttributeOpenToken>() != null)
            {
                stream.Read <AttributeOpenToken>();
                stream.Read <AttributeCloseToken>();
                parameter.IsArray = true;
            }
            if (stream.Peek <EqualsOperatorToken>() != null)
            {
                stream.Read <EqualsOperatorToken>();
                parameter.DefaultValue = ClassFeatureAst.ReadDefaultValue(stream, parameter.Type);
            }
            return(parameter);
        }
예제 #2
0
        /// <summary>
        /// </summary>
        /// <returns></returns>
        /// <remarks>
        /// See http://www.dmtf.org/sites/default/files/standards/documents/DSP0221_3.0.0a.pdf
        /// A.5 Class declaration
        ///
        ///     classDeclaration = [ qualifierList ] CLASS className [ superClass ]
        ///                        "{" *classFeature "}" ";"
        ///
        ///     className        = elementName
        ///     superClass       = ":" className
        ///     classFeature     = structureFeature /
        ///                        methodDeclaration
        ///     CLASS            = "class" ; keyword: case insensitive
        ///
        /// </remarks>
        internal static ClassDeclarationAst ParseClassAst(ParserStream stream, QualifierListAst qualifiers)
        {
            var node = new ClassDeclarationAst();

            // [ qualifierList ]
            node.Qualifiers = qualifiers;

            // CLASS
            stream.ReadIdentifier(Keywords.CLASS);

            // className
            var className = stream.Read <IdentifierToken>();

            if (!StringValidator.IsClassName(className.Name))
            {
                throw new InvalidOperationException("Identifer is not a valid class name.");
            }
            node.ClassName = className;

            // [ superClass ]
            if (stream.Peek <ColonToken>() != null)
            {
                stream.Read <ColonToken>();
                var superclass = stream.Read <IdentifierToken>();
                if (!StringValidator.IsClassName(className.Name))
                {
                    throw new InvalidOperationException("Identifer is not a valid superclass name.");
                }
                node.Superclass = superclass;
            }

            // "{"
            stream.Read <BlockOpenToken>();

            // *classFeature
            while (!stream.Eof)
            {
                var peek = stream.Peek() as BlockCloseToken;
                if (peek != null)
                {
                    break;
                }
                var classFeature = ClassFeatureAst.Parse(stream);
                node.Features.Add(classFeature);
            }

            // "}" ";"
            stream.Read <BlockCloseToken>();
            stream.Read <StatementEndToken>();

            return(node);
        }
예제 #3
0
        /// <summary>
        /// </summary>
        /// <returns></returns>
        /// <remarks>
        /// See http://www.dmtf.org/sites/default/files/standards/documents/DSP0221_3.0.0a.pdf
        /// A.5 Class declaration
        ///
        ///     classFeature     = structureFeature / methodDeclaration
        ///
        ///     structureFeature = structureDeclaration / ; local structure
        ///                        enumDeclaration /      ; local enumeration
        ///                        propertyDeclaration
        ///
        ///     structureDeclaration = [ qualifierList ] STRUCTURE structureName
        ///                            [ superstructure ]
        ///                            "{" *structureFeature "}" ";"
        ///
        ///     enumDeclaration = enumTypeHeader
        ///                       enumName ":" enumTypeDeclaration ";"
        ///     enumTypeHeader  = [ qualifierList ] ENUMERATION
        ///
        ///     propertyDeclaration = [ qualifierList ] ( primitivePropertyDeclaration /
        ///                                               complexPropertyDeclaration /
        ///                                               enumPropertyDeclaration
        ///                                               referencePropertyDeclaration ) ";"
        ///
        ///     methodDeclaration = [ qualifierList ] ( ( returnDataType [ array ] ) /
        ///                                             VOID ) methodName
        ///                                             "(" [ parameterList ] ")" ";"
        ///
        /// </remarks>
        internal static ClassFeatureAst Parse(ParserStream stream)
        {
            // all classFeatures start with an optional "[ qualifierList ]"
            var qualifierList = default(QualifierListAst);
            var peek          = stream.Peek() as AttributeOpenToken;

            if ((peek as AttributeOpenToken) != null)
            {
                qualifierList = QualifierListAst.Parse(stream);
            }

            // we now need to work out if it's a structureDeclaration, enumDeclaration,
            // propertyDeclaration or methodDeclaration
            var identifier     = stream.Peek <IdentifierToken>();
            var identifierName = identifier.GetNormalizedName();

            if (identifier == null)
            {
                throw new UnexpectedTokenException(peek);
            }
            else if (identifierName == Keywords.STRUCTURE)
            {
                // structureDeclaration
                throw new UnsupportedTokenException(identifier);
            }
            else if (identifierName == Keywords.ENUMERATION)
            {
                // enumDeclaration
                throw new UnsupportedTokenException(identifier);
            }
            else
            {
                // propertyDeclaration or methodDeclaration
                return(ClassFeatureAst.ParseMemberDeclaration(stream, qualifierList));
            }
        }
예제 #4
0
        /// <summary>
        /// </summary>
        /// <returns></returns>
        /// <remarks>
        /// See http://www.dmtf.org/sites/default/files/standards/documents/DSP0221_3.0.0a.pdf
        /// A.10 Property declaration
        /// Whitespace as defined in 5.2 is allowed between the elements of the rules in this ABNF section.
        ///
        ///     propertyDeclaration = [ qualifierList ] ( primitivePropertyDeclaration /
        ///                                               complexPropertyDeclaration /
        ///                                               enumPropertyDeclaration /
        ///                                               referencePropertyDeclaration) ";"
        ///
        ///     primitivePropertyDeclaration = primitiveType propertyName [ array ]
        ///                                    [ "=" primitiveTypeValue]
        ///     complexPropertyDeclaration   = structureOrClassName propertyName [ array ]
        ///                                    [ "=" ( complexTypeValue / aliasIdentifier ) ]
        ///     enumPropertyDeclaration      = enumName propertyName [ array ]
        ///                                    [ "=" enumTypeValue]
        ///     referencePropertyDeclaration = classReference propertyName [ array ]
        ///                                    [ "=" referenceTypeValue ]
        ///
        ///     array                        = "[" "]"
        ///     propertyName                 = IDENTIFIER
        ///     structureOrClassName         = IDENTIFIER
        ///     classReference               = DT_REFERENCE
        ///     DT_REFERENCE                 = className REF
        ///     REF                          = "ref" ; keyword: case insensitive
        ///
        /// A.11 Method declaration
        /// Whitespace as defined in 5.2 is allowed between the elements of the rules in this ABNF section.
        ///
        ///     methodDeclaration = [ qualifierList ] ( ( returnDataType [ array ] ) /
        ///                         VOID ) methodName
        ///                         "(" [ parameterList ] ")" ";"
        ///
        ///     returnDataType    = primitiveType /
        ///                         structureOrClassName /
        ///                         enumName /
        ///                         classReference
        ///     array             = "[" "]"
        ///     methodName        = IDENTIFIER
        ///     classReference    = DT_REFERENCE
        ///     DT_REFERENCE      = className REF
        ///     REF               = "ref" ; keyword: case insensitive
        ///     VOID              = "void" ; keyword: case insensitive
        ///     parameterList     = parameterDeclaration *( "," parameterDeclaration )
        ///
        private static ClassFeatureAst ParseMemberDeclaration(ParserStream stream, QualifierListAst qualifiers)
        {
            // primitiveType / structureOrClassName / enumName / classReference
            var returnType = stream.Read <IdentifierToken>();

            var @ref = default(IdentifierToken);

            if (stream.PeekIdentifier(Keywords.REF))
            {
                @ref = stream.ReadIdentifier(Keywords.REF);
            }

            // [ array ]
            var returnTypeIsArray = false;

            if (stream.Peek <AttributeOpenToken>() != null)
            {
                stream.Read <AttributeOpenToken>();
                stream.Read <AttributeCloseToken>();
                returnTypeIsArray = true;
            }

            // propertyName / methodName
            var memberName = stream.Read <IdentifierToken>();

            if ((stream.Peek <ParenthesesOpenToken>() != null) && (@ref == null))
            {
                // read the remainder of a methodDeclaration
                var ast = new MethodDeclarationAst
                {
                    Qualifiers        = qualifiers,
                    Name              = memberName,
                    ReturnType        = returnType,
                    ReturnTypeIsArray = returnTypeIsArray
                };
                // "("
                stream.Read <ParenthesesOpenToken>();
                //  [ parameterList ]
                if (stream.Peek <ParenthesesCloseToken>() == null)
                {
                    while (!stream.Eof)
                    {
                        if (ast.Parameters.Count > 0)
                        {
                            stream.Read <CommaToken>();
                        }
                        var parameter = ParameterDeclarationAst.Parse(stream);
                        ast.Parameters.Add(parameter);
                        if (stream.Peek <ParenthesesCloseToken>() != null)
                        {
                            break;
                        }
                    }
                }
                // ")" ";"
                stream.Read <ParenthesesCloseToken>();
                stream.Read <StatementEndToken>();
                return(ast);
            }
            else
            {
                // read the remainder of a propertyDeclaration
                var ast = new PropertyDeclarationAst
                {
                    Qualifiers = qualifiers,
                    Name       = memberName,
                    Type       = returnType,
                    IsRef      = (@ref != null)
                };
                if (stream.Peek <AttributeOpenToken>() != null)
                {
                    stream.Read <AttributeOpenToken>();
                    stream.Read <AttributeCloseToken>();
                    ast.IsArray = true;
                }
                if (stream.Peek <EqualsOperatorToken>() != null)
                {
                    stream.Read <EqualsOperatorToken>();
                    ast.Initializer = ClassFeatureAst.ReadDefaultValue(stream, returnType);
                }
                stream.Read <StatementEndToken>();
                return(ast);
            }
        }