/// <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); }
/// <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); }
/// <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)); } }
/// <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); } }