// STRUCT_BODY -> {ATTR_STRUCT_ELEMENT} // ATTR_STRUCT_ELEMENT -> [ATTRIBUTES] STRUCT_ELEMENT // STRUCT_ELEMENT -> STRUCT_FIELD | ENUM_DECL | CONSTANT_DECL func (p *Parser) parseStructBody(mojomStruct *mojom.MojomStruct) bool { if !p.OK() { return p.OK() } p.pushChildNode("structBody") defer p.popNode() // The struct body forms a new scope. p.pushScope(mojomStruct.InitAsScope(p.currentScope)) defer p.popScope() rbraceFound := false for attributes := p.parseAttributes(); !rbraceFound; attributes = p.parseAttributes() { if !p.OK() { return false } nextToken := p.peekNextToken("I was parsing a struct body.") var duplicateNameError error = nil switch nextToken.Kind { case lexer.Name: mojomStruct.AddField(p.parseStructField(attributes)) case lexer.Enum: if mojomEnum := p.parseEnumDecl(attributes); mojomEnum != nil { duplicateNameError = mojomStruct.AddEnum(mojomEnum) } case lexer.Const: if constant := p.parseConstDecl(attributes); constant != nil { duplicateNameError = mojomStruct.AddConstant(constant) } case lexer.RBrace: rbraceFound = true if attributes != nil { message := "Struct body ends with extraneouss attributes." p.err = &ParseError{ParserErrorCodeBadAttributeLocation, message} } break default: p.unexpectedTokenError(nextToken, "field, enum or constant declaration") return false } if p.OK() && duplicateNameError != nil { p.err = &ParseError{ParserErrorCodeDuplicateDeclaration, duplicateNameError.Error()} return false } } if p.OK() { mojomStruct.ComputeFieldOrdinals() } return p.OK() }
// STRUCT_BODY -> {ATTR_STRUCT_ELEMENT} // ATTR_STRUCT_ELEMENT -> [ATTRIBUTES] STRUCT_ELEMENT // STRUCT_ELEMENT -> STRUCT_FIELD | ENUM_DECL | CONSTANT_DECL func (p *Parser) parseStructBody(mojomStruct *mojom.MojomStruct) bool { if !p.OK() { return p.OK() } p.pushChildNode("structBody") defer p.popNode() // The struct body forms a new scope. p.pushScope(mojomStruct.InitAsScope(p.currentScope)) defer p.popScope() rbraceFound := false for attributes := p.parseAttributes(); !rbraceFound; attributes = p.parseAttributes() { if !p.OK() { return false } nextToken := p.peekNextToken("I was parsing a struct body.") dupeMessage := "" switch nextToken.Kind { case lexer.NAME: mojomStruct.AddField(p.parseStructField(attributes)) case lexer.ENUM: if mojomEnum, nameToken := p.parseEnumDecl(attributes); mojomEnum != nil { dupeMessage = p.duplicateNameMessage(mojomStruct.AddEnum(mojomEnum), nameToken) } case lexer.CONST: if constant, nameToken := p.parseConstDecl(attributes); constant != nil { dupeMessage = p.duplicateNameMessage(mojomStruct.AddConstant(constant), nameToken) } case lexer.RBRACE: rbraceFound = true if attributes != nil { message := "Struct body ends with extranesous attributes." p.err = &ParseError{E_BAD_ATTRIBUTE_LOCATION, message} } break default: p.unexpectedTokenError(nextToken, "field, enum or constant declaration") return false } if p.OK() && len(dupeMessage) > 0 { p.err = &ParseError{E_DUPLICATE_DECLARATION, dupeMessage} return false } } if p.OK() { mojomStruct.ComputeFieldOrdinals() } return p.OK() }