/* “GRAMMAR OF A PROTOCOL DECLARATION protocol-declaration → attributes opt protocol protocol-name type-inheritance-clause opt protocol-body protocol-name → identifier protocol-body → {protocol-member-declarations opt} protocol-member-declaration → protocol-property-declaration protocol-member-declaration → protocol-method-declaration protocol-member-declaration → protocol-initializer-declaration protocol-member-declaration → protocol-subscript-declaration protocol-member-declaration → protocol-associated-type-declaration protocol-member-declarations → protocol-member-declaration protocol-member-declarations opt ” “GRAMMAR OF A PROTOCOL PROPERTY DECLARATION protocol-property-declaration → variable-declaration-head variable-name type-annotation getter-setter-keyword-block ” “GRAMMAR OF A PROTOCOL METHOD DECLARATION protocol-method-declaration → function-head function-name generic-parameter-clause opt function-signature ” “GRAMMAR OF A PROTOCOL INITIALIZER DECLARATION protocol-initializer-declaration → initializer-head generic-parameter-clause opt parameter-clause ” “GRAMMAR OF A PROTOCOL SUBSCRIPT DECLARATION protocol-subscript-declaration → subscript-head subscript-result getter-setter-keyword-block” “GRAMMAR OF A PROTOCOL ASSOCIATED TYPE DECLARATION protocol-associated-type-declaration → typealias-head type-inheritance-clause opt typealias-assignment opt ” */ DeclarationPtr Parser::parseProtocol(const std::vector<AttributePtr>& attrs) { Token token; expect(Keyword::Protocol); ProtocolDefPtr ret = nodeFactory->createProtocol(token.state); ret->setAttributes(attrs); expect_identifier(token); TypeIdentifierPtr typeId = nodeFactory->createTypeIdentifier(token.state); typeId->setName(token.token); ret->setIdentifier(typeId); if(match(L":")) { do { TypeIdentifierPtr protocol = parseTypeIdentifier(); ret->addParent(protocol); }while(match(L",")); } expect(L"{"); Flags f(this); f += UNDER_PROTOCOL; while(!predicate(L"}")) { DeclarationPtr decl = parseDeclaration(); ret->addDeclaration(decl); } expect(L"}"); return ret; }
/* union-style-enum → enum-name generic-parameter-clause opt{union-style-enum-members opt} union-style-enum-members → union-style-enum-member union-style-enum-members opt union-style-enum-member → declaration | union-style-enum-case-clause union-style-enum-case-clause → attributes opt case union-style-enum-case-list union-style-enum-case-list → union-style-enum-case | union-style-enum-case,union-style-enum-case-list union-style-enum-case → enum-case-name tuple-type opt */ DeclarationPtr Parser::parseUnionEnum(const std::vector<AttributePtr>& attrs, const std::wstring& name) { Token token; expect(L"{", token); EnumDefPtr ret = nodeFactory->createEnum(token.state); ret->setAttributes(attrs); TypeIdentifierPtr typeId = nodeFactory->createTypeIdentifier(token.state); typeId->setName(name); ret->setIdentifier(typeId); while(!predicate(L"}")) { if(match(Keyword::Case)) { do { expect_identifier(token); TupleTypePtr associatedType = NULL; if(predicate(L"(")) { associatedType = parseTupleType(); } ret->addAssociatedType(token.token, associatedType); }while(match(L",")); } else { DeclarationPtr decl = parseDeclaration(); ret->addDeclaration(decl); } } expect(L"}"); return ret; }
/* raw-value-style-enum → enum-name generic-parameter-clause opt : type-identifier{raw-value-style-enum-members opt} raw-value-style-enum-members → raw-value-style-enum-member raw-value-style-enum-members opt raw-value-style-enum-member → declaration | raw-value-style-enum-case-clause raw-value-style-enum-case-clause → attributes opt case raw-value-style-enum-case-list raw-value-style-enum-case-list → raw-value-style-enum-case | raw-value-style-enum-case,raw-value-style-enum-case-list raw-value-style-enum-case → enum-case-name raw-value-assignment opt raw-value-assignment → =literal */ DeclarationPtr Parser::parseRawValueEnum(const std::vector<AttributePtr>& attrs, const std::wstring& name, const TypeIdentifierPtr& baseType) { Token token; expect(L"{", token); EnumDefPtr ret = nodeFactory->createEnum(token.state); ret->setAttributes(attrs); TypeIdentifierPtr typeId = nodeFactory->createTypeIdentifier(token.state); typeId->setName(name); ret->setIdentifier(typeId); ret->addParent(baseType); while(!predicate(L"}")) { if(match(Keyword::Case)) { do { expect_identifier(token); ExpressionPtr val = NULL; if(match(L"=")) { val = parseLiteral(); } ret->addConstant(token.token, val); }while(match(L",")); } else { DeclarationPtr decl = parseDeclaration(); ret->addDeclaration(decl); } } expect(L"}"); return ret; }
/* GRAMMAR OF A TYPE IDENTIFIER type-identifier → type-name generic-argument-clause opt | type-name generic-argument-clause opt . type-identifier type-name → identifier */ TypeIdentifierPtr Parser::parseTypeIdentifier() { Token token; expect_next(token); if(token.type != TokenType::Identifier || (token.identifier.keyword != Keyword::_ && token.identifier.keyword != Keyword::SelfType)) { ResultItems items = {token.token}; error(token, Errors::E_EXPECT_IDENTIFIER_1, items); return nullptr; } TypeIdentifierPtr ret = nodeFactory->createTypeIdentifier(token.state); ret->setName(token.token); ENTER_CONTEXT(TokenizerContextType); if(match(L"<")) { do { TypeNodePtr arg = parseType(); ret->addGenericArgument(arg); }while(match(L",")); expect(L">"); } if(match(L".")) { //read next TypeIdentifierPtr next = parseTypeIdentifier(); ret->setNestedType(next); } return ret; }
/* “GRAMMAR OF A STRUCTURE DECLARATION struct-declaration → attributes opt struct struct-name generic-parameter-clause opt type-inheritance-clause opt struct-body struct-name → identifier struct-body → {declarations opt}” */ DeclarationPtr Parser::parseStruct(const std::vector<AttributePtr>& attrs) { Token token; expect(Keyword::Struct); StructDefPtr ret = nodeFactory->createStruct(token.state); ret->setAttributes(attrs); expect_identifier(token); TypeIdentifierPtr typeId = nodeFactory->createTypeIdentifier(token.state); typeId->setName(token.token); ret->setIdentifier(typeId); if(predicate(L"<")) { GenericParametersDefPtr params = parseGenericParametersDef(); ret->setGenericParametersDef(params); } if(match(L":")) { do { TypeIdentifierPtr protocol = parseTypeIdentifier(); ret->addParent(protocol); }while(match(L",")); } Flags f(this); flags += UNDER_STRUCT; expect(L"{"); while(!predicate(L"}")) { DeclarationPtr decl = parseDeclaration(); ret->addDeclaration(decl); } expect(L"}"); return ret; }
GenericParametersDefPtr Parser::parseGenericParametersDef() { Token token; ENTER_CONTEXT(TokenizerContextType); expect(L"<", token); GenericParametersDefPtr ret = nodeFactory->createGenericParametersDef(token.state); // generic-parameter-list → generic-parameter | generic-parameter,generic-parameter-list do { // generic-parameter → type-name // generic-parameter → type-name:type-identifier // generic-parameter → type-name:protocol-composition-type expect_identifier(token); std::wstring typeName = token.token; TypeIdentifierPtr typeId = nodeFactory->createTypeIdentifier(token.state); typeId->setName(typeName); ret->addGenericType(typeId); if(match(L":")) { TypeNodePtr expected; if(predicate(L"protocol")) expected = parseProtocolComposition(); else expected = parseTypeIdentifier(); GenericConstraintDefPtr c = nodeFactory->createGenericConstraintDef(token.state); typeId = nodeFactory->createTypeIdentifier(token.state); typeId->setName(typeName); c->setIdentifier(typeId); c->setConstraintType(GenericConstraintDef::AssignableTo); c->setExpectedType(expected); ret->addConstraint(c); } } while (match(L",")); // requirement-clause → where requirement-list if(match(Keyword::Where)) { // requirement-list → requirement | requirement,requirement-list do { TypeIdentifierPtr type = parseTypeIdentifier(); // requirement → conformance-requirement | same-type-requirement if(match(L":")) { // conformance-requirement → type-identifier:type-identifier // conformance-requirement → type-identifier:protocol-composition-type TypeNodePtr expected; if (predicate(L"protocol")) expected = this->parseProtocolComposition(); else expected = parseTypeIdentifier(); GenericConstraintDefPtr c = nodeFactory->createGenericConstraintDef(*type->getSourceInfo()); c->setConstraintType(GenericConstraintDef::AssignableTo); c->setIdentifier(type); c->setExpectedType(expected); ret->addConstraint(c); } else if(match(L"==")) { // same-type-requirement → type-identifier==type-identifier GenericConstraintDefPtr c = nodeFactory->createGenericConstraintDef(*type->getSourceInfo()); ret->addConstraint(c); c->setIdentifier(type); TypeIdentifierPtr expectedType = parseTypeIdentifier(); c->setConstraintType(GenericConstraintDef::EqualsTo); c->setExpectedType(expectedType); } } while (match(L",")); } expect(L">"); return ret; }